Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[panic] panic! called when "reference types found but safepoints not enabled" #1156

Open
pventuzelo opened this issue Nov 25, 2019 · 3 comments
Labels
bug Incorrect behavior in the current implementation that needs fixing cranelift:E-easy Issues suitable for newcomers to investigate, including Rust newcomers! cranelift Issues related to the Cranelift code generator

Comments

@pventuzelo
Copy link
Contributor

What are the steps to reproduce the issue? Can you include a CLIF test case, ideally reduced with the bugpoint clif-util command?

Download panic_ref_type_not_enabled.zip

$ unzip panic_ref_type_not_enabled.zip
$ ./target/release/clif-util wasm panic_ref_type_not_enabled.wasm --target x86_64
thread 'main' panicked at 'reference types were found but safepoints were not enabled.', cranelift-codegen/src/regalloc/context.rs:219:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

What do you expect to happen? What does actually happen? Does it panic, and if so, with which assertion?

I would expect an error to be through instead of panicking. There is a call to the panic! macro here:
https://github.com/bytecodealliance/cranelift/blob/c54fc845c45b2929bdf36635c90a363e380cf805/cranelift-codegen/src/regalloc/context.rs#L215-L221

Which Cranelift version / commit hash / branch are you using?

Cranelift version :

$ ./target/release/clif-util --version
Cranelift code generator utility 0.42.0

commit hash: c54fc84
branch: master

If relevant, can you include some extra information about your environment? (Rust version, operating system, architecture...)

$ echo "`rustc -V` | `uname -ovm`"
rustc 1.38.0-nightly (2d1a551e1 2019-08-08) | bytecodealliance/wasmtime#1026-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64 GNU/Linux

More details:

Execution with verbosity and print:

./target/release/clif-util wasm panic_ref_type_not_enabled.wasm --target x86_64 -v -p
Handling: "panic_ref_type_not_enabled.wasm"
Translating... ok
Compiling... 
function u0:2(i32 [%rdi], i64 vmctx [%rsi], i64 fp [%rbp], i64 csr [%r15]) -> i32 [%rax], i64 fp [%rbp], i64 csr [%r15] system_v {
    ss0 = spill_slot 4, offset -28
    ss1 = incoming_arg 24, offset -24
    gv0 = vmctx
    gv1 = vmctx
    sig0 = (i32 [%rdi], i64 vmctx [%rsi]) system_v
    fn0 = u0:0 sig0

                                ebb0(v0: i32 [%rdi], v1: i64 [%rsi], v28: i64 [%rbp], v29: i64 [%r15]):
                                    v4 -> v1
                                    v6 -> v1
                                    v9 -> v1
                                    v10 -> v1
                                    v16 -> v1
                                    v17 -> v1
                                    v19 -> v1
[RexOp1pushq#50]                    x86_push v28
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
[RexOp1pushq#50]                    x86_push v29
[RexOp1adjustsp_ib#d083]            adjust_sp_down_imm 8
@01ab [RexOp1ldDisp8#8b,%rax]       v26 = load.i32 notrap aligned v1+88
@01ab [RexOp1spillSib32#89,ss0]     v5 = spill v26
                                    v23 -> v5
@01af [RexOp1ldDisp8#8b,%rax]       v7 = load.i32 notrap aligned v1+88
@01b3 [RexOp1rr#01,%rax]            v8 = iadd v7, v0
@01b4 [RexOp1stDisp8#89]            store notrap aligned v8, v1+88
@01b6 [RexOp1ldDisp8#8b,%rax]       v11 = load.i32 notrap aligned v1+88
@01ba [RexOp1r_ib#83,%rax]          v13 = iadd_imm v11, 15
@01bd [RexOp1r_ib#4083,%rax]        v15 = band_imm v13, -16
@01be [RexOp1stDisp8#89]            store notrap aligned v15, v1+88
@01c0 [RexOp1ldDisp8#8b,%rax]       v18 = load.i32 notrap aligned v1+88
@01c2 [RexOp1ldDisp8#8b,%rcx]       v20 = load.i32 notrap aligned v1+96
@01c4 [RexOp1rcmp#39,%rflags]       v25 = ifcmp v18, v20
@01c5 [RexOp1brib#70]               brif slt v25, ebb2
@01c9 [RexOp1fnaddr8#80b8,%rax]     v24 = func_addr.i64 fn0
@01c9 [RexOp1call_r#20ff]           call_indirect sig0, v24(v0, v1)
@01cb [-]                           fallthrough ebb2

                                ebb2:
@01ce [RexOp1fillSib32#8b,%r15]     v27 = fill.i32 v5
@01ce [RexOp1rmov#89]               regmove v27, %r15 -> %rax
[RexOp1adjustsp_ib#8083]            adjust_sp_up_imm 8
[RexOp1popq#58,%r15]                v31 = x86_pop.i64 
[RexOp1popq#58,%rbp]                v30 = x86_pop.i64 
@01ce [Op1ret#c3]                   return v27, v30, v31
}



function u0:3(i64 vmctx [%rdi], i64 fp [%rbp]) -> i32 [%rax], i64 fp [%rbp] system_v {
    ss0 = incoming_arg 16, offset -16
    gv0 = vmctx

                                ebb0(v0: i64 [%rdi], v4: i64 [%rbp]):
                                    v2 -> v0
[RexOp1pushq#50]                    x86_push v4
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
@01d2 [RexOp1ldDisp8#8b,%rax]       v3 = load.i32 notrap aligned v0+88
[RexOp1popq#58,%rbp]                v5 = x86_pop.i64 
@01d4 [Op1ret#c3]                   return v3, v5
}



function u0:4(i32 [%rdi], i64 vmctx [%rsi], i64 fp [%rbp]) -> i64 fp [%rbp] system_v {
    ss0 = incoming_arg 16, offset -16
    gv0 = vmctx

                                ebb0(v0: i32 [%rdi], v1: i64 [%rsi], v3: i64 [%rbp]):
                                    v2 -> v1
[RexOp1pushq#50]                    x86_push v3
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
@01da [RexOp1stDisp8#89]            store notrap aligned v0, v1+88
@01dc [-]                           fallthrough ebb1

                                ebb1:
[RexOp1popq#58,%rbp]                v4 = x86_pop.i64 
@01dc [Op1ret#c3]                   return v4
}



function u0:5(i32 [%rdi], i32 [%rsi], i64 vmctx [%rdx], i64 fp [%rbp]) -> i64 fp [%rbp] system_v {
    ss0 = incoming_arg 16, offset -16
    gv0 = vmctx
    gv1 = vmctx

                                ebb0(v0: i32 [%rdi], v1: i32 [%rsi], v2: i64 [%rdx], v5: i64 [%rbp]):
                                    v3 -> v2
                                    v4 -> v2
[RexOp1pushq#50]                    x86_push v5
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
@01e1 [RexOp1stDisp8#89]            store notrap aligned v0, v2+88
@01e5 [RexOp1stDisp8#89]            store notrap aligned v1, v2+96
@01e7 [-]                           fallthrough ebb1

                                ebb1:
[RexOp1popq#58,%rbp]                v6 = x86_pop.i64 
@01e7 [Op1ret#c3]                   return v6
}



function u0:6(i32 [%rdi], i32 [%rsi], i64 vmctx [%rdx], i64 fp [%rbp]) -> i64 fp [%rbp] system_v {
    ss0 = incoming_arg 16, offset -16
    gv0 = vmctx
    gv1 = vmctx

                                ebb0(v0: i32 [%rdi], v1: i32 [%rsi], v2: i64 [%rdx], v10: i64 [%rbp]):
                                    v3 -> v2
                                    v8 -> v2
                                    v9 -> v2
[RexOp1pushq#50]                    x86_push v10
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
@01ea [RexOp1ldDisp8#8b,%rax]       v4 = load.i32 notrap aligned v2+104
@01ef [RexOp1tjccb#75]              brnz v4, ebb2
@01f3 [RexOp1stDisp8#89]            store notrap aligned v0, v2+104
@01f7 [RexOp1stDisp8#89]            store notrap aligned v1, v2+112
@01f9 [-]                           fallthrough ebb2

                                ebb2:
@01fa [-]                           fallthrough ebb1

                                ebb1:
[RexOp1popq#58,%rbp]                v11 = x86_pop.i64 
@01fa [Op1ret#c3]                   return v11
}



; Exported as "_main"
function u0:7(i32 [%rdi], i32 [%rsi], i64 vmctx [%rdx], i64 fp [%rbp], i64 csr [%r15]) -> i32 [%rax], i64 fp [%rbp], i64 csr [%r15] system_v {
    ss0 = spill_slot 8, offset -32
    ss1 = incoming_arg 24, offset -24
    gv0 = vmctx
    gv1 = vmctx
    gv2 = vmctx
    gv3 = load.i64 notrap aligned readonly gv2
    heap0 = static gv3, min 0, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32
    sig0 = (i32 [%rdi], i64 vmctx [%rsi]) system_v
    fn0 = u0:0 sig0

                                ebb0(v0: i32 [%rdi], v1: i32 [%rsi], v33: i64 [%rdx], v40: i64 [%rbp], v41: i64 [%r15]):
[RexOp1pushq#50]                    x86_push v40
[RexOp1copysp#8089]                 copy_special %rsp -> %rbp
[RexOp1pushq#50]                    x86_push v41
[RexOp1adjustsp_ib#d083]            adjust_sp_down_imm 8
[RexOp1spillSib32#8089,ss0]         v2 = spill v33
                                    v5 -> v2
                                    v7 -> v2
                                    v11 -> v2
                                    v12 -> v2
                                    v14 -> v2
@0204 [RexOp1fillSib32#808b,%r15]   v34 = fill v2
@0204 [RexOp1ldDisp8#8b,%rax]       v8 = load.i32 notrap aligned v34+88
@0208 [RexOp1r_ib#83,%rax]          v10 = iadd_imm v8, 48
@0209 [RexOp1fillSib32#808b,%r15]   v35 = fill v2
@0209 [RexOp1stDisp8#89]            store notrap aligned v10, v35+88
@020b [RexOp1fillSib32#808b,%r15]   v36 = fill v2
@020b [RexOp1ldDisp8#8b,%rax]       v13 = load.i32 notrap aligned v36+88
@020d [RexOp1fillSib32#808b,%r15]   v37 = fill v2
@020d [RexOp1ldDisp8#8b,%rcx]       v15 = load.i32 notrap aligned v37+96
@020f [RexOp1rcmp#39,%rflags]       v32 = ifcmp v13, v15
@0210 [RexOp1brib#70]               brif slt v32, ebb2
@0212 [RexOp1pu_id#b8,%rax]         v18 = iconst.i32 48
@0214 [RexOp1fnaddr8#80b8,%rcx]     v29 = func_addr.i64 fn0
@0214 [RexOp1fillSib32#808b,%r15]   v38 = fill v2
@0214 [RexOp1rmov#89]               regmove v18, %rax -> %rdi
@0214 [RexOp1rmov#8089]             regmove v38, %r15 -> %rsi
@0214 [RexOp1call_r#20ff]           call_indirect sig0, v29(v18, v38)
@0216 [-]                           fallthrough ebb2

                                ebb2:
@0230 [RexOp1pu_id#b8,%rax]         v26 = iconst.i32 0
@0232 [RexOp1umr#89,%rax]           v30 = uextend.i64 v26
@0232 [RexOp1fillSib32#808b,%r15]   v39 = fill.i64 v2
@0232 [RexOp1ld#808b,%rcx]          v31 = load.i64 notrap aligned readonly v39
@0232 [RexOp1ldWithIndexDisp8#808b,%rax] v28 = load_complex.i64 v31+v30+32
@0235 [Op2trap#40b]                 trap unreachable
}


thread 'main' panicked at 'reference types were found but safepoints were not enabled.', cranelift-codegen/src/regalloc/context.rs:219:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
@bnjbvr
Copy link
Member

bnjbvr commented Dec 2, 2019

Good point, it should probably raise an error instead. Thanks for opening an issue! I'll call it a simple bug if anybody wants to dive in in the code base: this requires changing the panic in cranelift-codegen/src/regalloc/context.rs and returning an appropriate error variant instead of panicking.

@jpmcb
Copy link

jpmcb commented Jan 9, 2020

Howdy! I was wondering if this would be a good first issue to try out? I'm new to contributing but hoping to get involved.

I've read the testing cranelift doc but I'm still not sure how one would go about creating a *.clif test. Any pointers would be great!

@bnjbvr
Copy link
Member

bnjbvr commented Jan 10, 2020

Hi! Yes, you can start with the following test case:

test compile
target x86_64

function %test(r64) -> r64 {
    ebb0(v0: r64):
        v1 = null.r64
        v2 = is_null v0
        brz v2, ebb2(v0)
        jump ebb2(v1)
    ebb2(v3: r64):
        return v3
}

When you run it with cargo run test /tmp/a.clif, it will complain that we're running into this error. You can start from there.

Ideally, we'd have the verifier emit this error, when checking the function's body IR (in cranelift-codegen/src/verifier/mod.rs).

@alexcrichton alexcrichton transferred this issue from bytecodealliance/cranelift Feb 28, 2020
@alexcrichton alexcrichton added cranelift:E-easy Issues suitable for newcomers to investigate, including Rust newcomers! bug Incorrect behavior in the current implementation that needs fixing cranelift Issues related to the Cranelift code generator labels Feb 28, 2020
arkpar pushed a commit to paritytech/wasmtime that referenced this issue Mar 4, 2020
…codealliance#1156

In some cases, compute_size() is used to choose between various different Encodings
before one has been assigned to an instruction. For x86, the REX.W bit is stored
in the Encoding. To share recipes between REX/non-REX, that bit must be inspected
by compute_size().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect behavior in the current implementation that needs fixing cranelift:E-easy Issues suitable for newcomers to investigate, including Rust newcomers! cranelift Issues related to the Cranelift code generator
Projects
None yet
4 participants