Stream: git-wasmtime

Topic: wasmtime / issue #8180 regalloc: multiple uses of vreg wi...


view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:15):

fitzgen added the bug label to Issue #8180.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:15):

fitzgen added the cranelift label to Issue #8180.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:15):

fitzgen opened issue #8180:

Getting this regalloc error in my GC branch. I've tweaked GC barriers but haven't done anything funky.

Wasm

This is the test Wasm...

            (module
                (table 1 externref)

                (func (export "run") (param externref)
                    i32.const 0
                    local.get 0
                    table.set 0
                )
            )

.clif Test Case

It gets translated to this CLIF...

function u0:0(i64 vmctx, i64, r64) fast {
        gv0 = vmctx
        gv1 = load.i64 notrap aligned readonly gv0+8
        gv2 = load.i64 notrap aligned gv1
        gv3 = vmctx
        gv4 = load.i64 notrap aligned gv3+72
        gv5 = load.i32 notrap aligned gv3+80
        table0 = dynamic gv4, min 0, bound gv5, element_size 8, index_type i32
        sig0 = (i64 vmctx, i64) system_v
        sig1 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
        sig2 = (i64 vmctx, i32 uext) -> i32 uext system_v
        stack_limit = gv2

                                    block0(v0: i64, v1: i64, v2: r64):
                                        v17 -> v0
                                        v29 -> v0
                                        v30 -> v0
    @002b                               v21 = load.i32 notrap aligned v0+80
    @0027                               v3 = iconst.i32 0
                                        v36 = icmp eq v21, v3  ; v3 = 0
    @002b                               brif v36, block8, block9

                                    block8 cold:
    @002b                               trap table_oob

                                    block9:
    @002b                               v24 = load.i64 notrap aligned v0+72
    @002b                               v28 = select_spectre_guard v36, v24, v24
                                        v4 -> v28
    @002b                               v5 = load.i32 notrap aligned table v28
    @002b                               v8 = is_null.r64 v2
    @002b                               brif v8, block3, block2

                                    block2:
    @002b                               v9 = load.i64 notrap aligned v2+8
                                        v32 = iconst.i64 1
    @002b                               v10 = iadd v9, v32  ; v32 = 1
    @002b                               store notrap aligned v10, v2+8
    @002b                               jump block3

                                    block3:
    @002b                               v11 = bitcast.i64 little v2
    @002b                               v12 = ireduce.i32 v11
    @002b                               store.i64 notrap aligned table v28, v12
    @002b                               v6 = uextend.i64 v5
    @002b                               v7 = bitcast.r64 little v6
    @002b                               v13 = is_null v7
    @002b                               brif v13, block7, block4

                                    block4:
    @002b                               v14 = load.i64 notrap aligned v7+8
                                        v33 = iconst.i64 -1
    @002b                               v15 = iadd v14, v33  ; v33 = -1
                                        v39 = iconst.i64 0
    @002b                               v16 = icmp eq v15, v39  ; v39 = 0
    @002b                               brif v16, block5, block6

                                    block5 cold:
    @002b                               v18 = load.i64 notrap aligned readonly v0+56
    @002b                               v19 = load.i64 notrap aligned readonly v18+200
    @002b                               v20 = bitcast.i64 v7
    @002b                               call_indirect sig0, v19(v0, v20)
    @002b                               jump block7

                                    block6:
                                        v40 = iadd.i64 v14, v33  ; v33 = -1
    @002b                               store notrap aligned v40, v7+8
    @002b                               jump block7

                                    block7:
    @002d                               jump block1

                                    block1:
    @002d                               return
    }

VCode

And that CLIF gets lowered to this VCode

VCode {
      Entry block: 0
      v195 := v232
      v198 := v231
      v199 := v230
      v200 := v229
      v201 := v228
      v203 := v227
      v205 := v194
      v206 := v205
      v207 := v226
      v208 := v207
      v209 := v225
      v210 := v224
      v212 := v223
      v215 := v221
      v216 := v220
      v217 := v208
      v218 := v222
    Block 0:
        (original IR block: block0)
        (successor: Block 11)
        (successor: Block 1)
        (instruction range: 0 .. 4)
      Inst 0: args %v192=%rdi %v193=%rsi %v194=%rdx
      Inst 1: movl    80(%v192), %v232l
      Inst 2: testl   %v195l, %v195l
      Inst 3: jz      label11; j label1
    Block 1:
        (original IR block: block9)
        (successor: Block 2)
        (successor: Block 3)
        (instruction range: 4 .. 12)
      Inst 4: movq    72(%v192), %v231
      Inst 5: testl   %v195l, %v195l
      Inst 6: cmovzq  %v198, %v198, %v230
      Inst 7: movl    0(%v199), %v229l
      Inst 8: cmpq    $0, %v194
      Inst 9: setz    %v228b
      Inst 10: testb   %v201b, %v201b
      Inst 11: jnz     label2; j label3
    Block 2:
        (successor: Block 4)
        (instruction range: 12 .. 13)
      Inst 12: jmp     label4
    Block 3:
        (original IR block: block2)
        (successor: Block 4)
        (instruction range: 13 .. 16)
      Inst 13: movl    $1, %v227l
      Inst 14: addq    %v203, 8(%v194)
      Inst 15: jmp     label4
    Block 4:
        (original IR block: block3)
        (successor: Block 5)
        (successor: Block 6)
        (instruction range: 16 .. 22)
      Inst 16: movq    %v199, 0(%v206)
      Inst 17: movl    %v200l, %v226l
      Inst 18: cmpq    $0, %v208
      Inst 19: setz    %v225b
      Inst 20: testb   %v209b, %v209b
      Inst 21: jnz     label5; j label6
    Block 5:
        (successor: Block 9)
        (instruction range: 22 .. 23)
      Inst 22: jmp     label9
    Block 6:
        (original IR block: block4)
        (successor: Block 8)
        (successor: Block 7)
        (instruction range: 23 .. 27)
      Inst 23: movq    8(%v208), %v224
      Inst 24: lea     -1(%v210), %v223
      Inst 25: testq   %v212, %v212
      Inst 26: jz      label8; j label7
    Block 7:
        (original IR block: block6)
        (successor: Block 9)
        (instruction range: 27 .. 30)
      Inst 27: lea     -1(%v210), %v222
      Inst 28: movq    %v218, 8(%v208)
      Inst 29: jmp     label9
    Block 8:
        (original IR block: block5)
        (successor: Block 9)
        (instruction range: 30 .. 34)
      Inst 30: movq    56(%v192), %v221
      Inst 31: movq    200(%v215), %v220
      Inst 32: call    *%v216
      Inst 33: jmp     label9
    Block 9:
        (original IR block: block7)
        (successor: Block 10)
        (instruction range: 34 .. 35)
      Inst 34: jmp     label10
    Block 10:
        (original IR block: block1)
        (instruction range: 35 .. 36)
      Inst 35: rets
    Block 11:
        (original IR block: block8)
        (instruction range: 36 .. 37)
      Inst 36: ud2 table_oob
    }

Steps to Reproduce

clif-util compile --target x86_64 regalloc-error.clif

Expected Results

No compilation errors

Actual Results

thread 'main' panicked at /home/nick/.cargo/registry/src/index.crates.io-6f17d22bba15001f/regalloc2-0.9.3/src/ion/liveranges.rs:884:57:
multiple uses of vreg with a Stack constraint are not supported

cc @cfallin @elliottt any ideas what's going on here? Error message is not super helpful.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:20):

cfallin commented on issue #8180:

@fitzgen would you perchance be able to get the RA2 liverange dump as well? You can get that by forcing the verbose flag to true in RegallocOptions (it's also set true according to some condition in CL that I forget -- we should really unify our "please log everything" settings!) and then grabbing the trace-level log output.

Also for our potential reproduction: does the CLIF show the same result when compiled on main?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:40):

fitzgen commented on issue #8180:

Here is the live range dump:

<details>

[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block11
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block11: []
[2024-03-19T15:39:07Z TRACE cranelift_codegen::isa::x64::inst::emit_state] adjust virtual sp offset by 0x0: 0x0 -> 0x0
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block10
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] MachBuffer: use_label_at_offset: offset 61 label MachLabel(6) kind JmpRel32
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block10: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block9
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] MachBuffer: use_label_at_offset: offset 66 label MachLabel(5) kind JmpRel32
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block9: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block5
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::vcode] emitting block Block(6)
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block5: []
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] MachBuffer: bind label MachLabel(6) at offset 70
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block8
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v220i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v192i fixed(p7i) was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v226i fixed(p6i) was_live = false
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] enter optimize_branches:
     b = [MachBranch { start: 7, end: 13, target: MachLabel(1), fixup: 0, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 26, end: 32, target: MachLabel(3), fixup: 1, inverted: Some([15, 132, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 59, end: 65, target: MachLabel(6), fixup: 2, inverted: Some([15, 132, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 65, end: 70, target: MachLabel(5), fixup: 3, inverted: None, labels_at_this_branch: [] }]
     l = [MachLabel(6)]
     f = [MachLabelFixup { label: MachLabel(1), offset: 9, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(3), offset: 28, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(6), offset: 61, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(5), offset: 66, kind: JmpRel32 }]
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v220i reg was_live = true
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] optimize_branches: last branch MachBranch { start: 65, end: 70, target: MachLabel(5), fixup: 3, inverted: None, labels_at_this_branch: [] } at off 70
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v221i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v221i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v192i reg was_live = true
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer]  -> more than one branch; prev_b = MachBranch { start: 59, end: 65, target: MachLabel(6), fixup: 2, inverted: Some([15, 132, 0, 0, 0, 0]), labels_at_this_branch: [] }
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer]  -> uncond follows a conditional, and conditional's target resolves to current offset
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block8: [192, 226]
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] truncate_last_branch: truncated MachBranch { start: 65, end: 70, target: MachLabel(5), fixup: 3, inverted: None, labels_at_this_branch: [] }; off now 65
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block7
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer]  -> reassigning target of condbr to MachLabel(5)
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: []
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] optimize_branches: last branch MachBranch { start: 59, end: 65, target: MachLabel(5), fixup: 2, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] } at off 65
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v222i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v226i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v222i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v224i reg was_live = false
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] leave optimize_branches:
     b = [MachBranch { start: 7, end: 13, target: MachLabel(1), fixup: 0, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 26, end: 32, target: MachLabel(3), fixup: 1, inverted: Some([15, 132, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 59, end: 65, target: MachLabel(5), fixup: 2, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }]
     l = [MachLabel(6)]
     f = [MachLabelFixup { label: MachLabel(1), offset: 9, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(3), offset: 28, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(5), offset: 61, kind: JmpRel32 }]
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block7: [224, 226]
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::abi] Epilogue: [movq    %rbp, %rsp, popq    %rbp, ret]
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block6
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: [192, 224, 226]
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::vcode] emitting block Block(1)
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v223i reg was_live = false
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] MachBuffer: bind label MachLabel(1) at offset 70
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v223i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v223i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v224i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v224i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v226i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computed liveins at block6: [192, 226]
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] enter optimize_branches:
     b = [MachBranch { start: 7, end: 13, target: MachLabel(1), fixup: 0, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 26, end: 32, target: MachLabel(3), fixup: 1, inverted: Some([15, 132, 0, 0, 0, 0]), labels_at_this_branch: [] }, MachBranch { start: 59, end: 65, target: MachLabel(5), fixup: 2, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }]
     l = [MachLabel(1)]
     f = [MachLabelFixup { label: MachLabel(1), offset: 9, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(3), offset: 28, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(5), offset: 61, kind: JmpRel32 }]
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] computing liveins for block4
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] optimize_branches: last branch MachBranch { start: 59, end: 65, target: MachLabel(5), fixup: 2, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] } at off 70
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges]  -> initial liveout set: [192, 226]
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] purge_latest_branches: removing branch MachBranch { start: 59, end: 65, target: MachLabel(5), fixup: 2, inverted: Some([15, 133, 0, 0, 0, 0]), labels_at_this_branch: [] }
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v225i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v225i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v225i reg was_live = true
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] leave optimize_branches:
     b = []
     l = [MachLabel(1)]
     f = [MachLabelFixup { label: MachLabel(1), offset: 9, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(3), offset: 28, kind: JmpRel32 }, MachLabelFixup { label: MachLabel(5), offset: 61, kind: JmpRel32 }]
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v226i reg was_live = true
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Def: v226i reg was_live = true
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::vcode] emitting block Block(3)
[2024-03-19T15:39:07Z TRACE cranelift_codegen::machinst::buffer] MachBuffer: bind label MachLabel(3) at offset 72
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v229i reg was_live = false
[2024-03-19T15:39:07Z TRACE regalloc2::ion::liveranges] op Use: v230i reg
[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 15:41):

fitzgen commented on issue #8180:

Reproduces on bd2ea901d3, which was main as of a couple weeks ago.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 16:05):

cfallin commented on issue #8180:

Here's a little more detail on the panic:

multiple uses of vreg with a Stack constraint are not supported: [Use { operand: Use: v226i fixed(p6i), pos: progpoint32-pre, slot: 2, weight: 35447 }, Use { operand: Use: v226i stack, pos: progpoint32-pre, slot: 255, weight: 35060 }]

Sure enough, Cranelift is asking regalloc2 to put v226 both on the stack, and in p6 (a physical register). This is now possible with overlapping LRs (Trevor's recent change) but wasn't for a long time, hence the panic.

progpoint32 corresponds to Inst 32, which is:

  Inst 32: call    *%v216

so I suspect we're both passing a ref as an argument (fixed register constraint according to ABI) and having it participate in the safepoint. Perhaps we should copy function args to new vregs? That's likely easier than re-engineering regalloc2's frontend to infer an overlap case here.

view this post on Zulip Wasmtime GitHub notifications bot (Mar 19 2024 at 16:14):

fitzgen commented on issue #8180:

so I suspect we're both passing a ref as an argument (fixed register constraint according to ABI) and having it participate in the safepoint.

What's interesting is that in this case, the value is not live after the call, so arguably doesn't need to participate in the safepoint, and also relatedly the call takes a pointer not a reference (although the i64 pointer is a bitcast of an r64 reference) for this very reason (the call is the ref-count-reached-zero-so-call-to-the-vm-to-drop-the-object call; see block5 cold in the CLIF).

view this post on Zulip Wasmtime GitHub notifications bot (Mar 21 2024 at 15:50):

fitzgen closed issue #8180:

Getting this regalloc error in my GC branch. I've tweaked GC barriers but haven't done anything funky.

Wasm

This is the test Wasm...

            (module
                (table 1 externref)

                (func (export "run") (param externref)
                    i32.const 0
                    local.get 0
                    table.set 0
                )
            )

.clif Test Case

It gets translated to this CLIF...

function u0:0(i64 vmctx, i64, r64) fast {
        gv0 = vmctx
        gv1 = load.i64 notrap aligned readonly gv0+8
        gv2 = load.i64 notrap aligned gv1
        gv3 = vmctx
        gv4 = load.i64 notrap aligned gv3+72
        gv5 = load.i32 notrap aligned gv3+80
        table0 = dynamic gv4, min 0, bound gv5, element_size 8, index_type i32
        sig0 = (i64 vmctx, i64) system_v
        sig1 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
        sig2 = (i64 vmctx, i32 uext) -> i32 uext system_v
        stack_limit = gv2

                                    block0(v0: i64, v1: i64, v2: r64):
                                        v17 -> v0
                                        v29 -> v0
                                        v30 -> v0
    @002b                               v21 = load.i32 notrap aligned v0+80
    @0027                               v3 = iconst.i32 0
                                        v36 = icmp eq v21, v3  ; v3 = 0
    @002b                               brif v36, block8, block9

                                    block8 cold:
    @002b                               trap table_oob

                                    block9:
    @002b                               v24 = load.i64 notrap aligned v0+72
    @002b                               v28 = select_spectre_guard v36, v24, v24
                                        v4 -> v28
    @002b                               v5 = load.i32 notrap aligned table v28
    @002b                               v8 = is_null.r64 v2
    @002b                               brif v8, block3, block2

                                    block2:
    @002b                               v9 = load.i64 notrap aligned v2+8
                                        v32 = iconst.i64 1
    @002b                               v10 = iadd v9, v32  ; v32 = 1
    @002b                               store notrap aligned v10, v2+8
    @002b                               jump block3

                                    block3:
    @002b                               v11 = bitcast.i64 little v2
    @002b                               v12 = ireduce.i32 v11
    @002b                               store.i64 notrap aligned table v28, v12
    @002b                               v6 = uextend.i64 v5
    @002b                               v7 = bitcast.r64 little v6
    @002b                               v13 = is_null v7
    @002b                               brif v13, block7, block4

                                    block4:
    @002b                               v14 = load.i64 notrap aligned v7+8
                                        v33 = iconst.i64 -1
    @002b                               v15 = iadd v14, v33  ; v33 = -1
                                        v39 = iconst.i64 0
    @002b                               v16 = icmp eq v15, v39  ; v39 = 0
    @002b                               brif v16, block5, block6

                                    block5 cold:
    @002b                               v18 = load.i64 notrap aligned readonly v0+56
    @002b                               v19 = load.i64 notrap aligned readonly v18+200
    @002b                               v20 = bitcast.i64 v7
    @002b                               call_indirect sig0, v19(v0, v20)
    @002b                               jump block7

                                    block6:
                                        v40 = iadd.i64 v14, v33  ; v33 = -1
    @002b                               store notrap aligned v40, v7+8
    @002b                               jump block7

                                    block7:
    @002d                               jump block1

                                    block1:
    @002d                               return
    }

VCode

And that CLIF gets lowered to this VCode

VCode {
      Entry block: 0
      v195 := v232
      v198 := v231
      v199 := v230
      v200 := v229
      v201 := v228
      v203 := v227
      v205 := v194
      v206 := v205
      v207 := v226
      v208 := v207
      v209 := v225
      v210 := v224
      v212 := v223
      v215 := v221
      v216 := v220
      v217 := v208
      v218 := v222
    Block 0:
        (original IR block: block0)
        (successor: Block 11)
        (successor: Block 1)
        (instruction range: 0 .. 4)
      Inst 0: args %v192=%rdi %v193=%rsi %v194=%rdx
      Inst 1: movl    80(%v192), %v232l
      Inst 2: testl   %v195l, %v195l
      Inst 3: jz      label11; j label1
    Block 1:
        (original IR block: block9)
        (successor: Block 2)
        (successor: Block 3)
        (instruction range: 4 .. 12)
      Inst 4: movq    72(%v192), %v231
      Inst 5: testl   %v195l, %v195l
      Inst 6: cmovzq  %v198, %v198, %v230
      Inst 7: movl    0(%v199), %v229l
      Inst 8: cmpq    $0, %v194
      Inst 9: setz    %v228b
      Inst 10: testb   %v201b, %v201b
      Inst 11: jnz     label2; j label3
    Block 2:
        (successor: Block 4)
        (instruction range: 12 .. 13)
      Inst 12: jmp     label4
    Block 3:
        (original IR block: block2)
        (successor: Block 4)
        (instruction range: 13 .. 16)
      Inst 13: movl    $1, %v227l
      Inst 14: addq    %v203, 8(%v194)
      Inst 15: jmp     label4
    Block 4:
        (original IR block: block3)
        (successor: Block 5)
        (successor: Block 6)
        (instruction range: 16 .. 22)
      Inst 16: movq    %v199, 0(%v206)
      Inst 17: movl    %v200l, %v226l
      Inst 18: cmpq    $0, %v208
      Inst 19: setz    %v225b
      Inst 20: testb   %v209b, %v209b
      Inst 21: jnz     label5; j label6
    Block 5:
        (successor: Block 9)
        (instruction range: 22 .. 23)
      Inst 22: jmp     label9
    Block 6:
        (original IR block: block4)
        (successor: Block 8)
        (successor: Block 7)
        (instruction range: 23 .. 27)
      Inst 23: movq    8(%v208), %v224
      Inst 24: lea     -1(%v210), %v223
      Inst 25: testq   %v212, %v212
      Inst 26: jz      label8; j label7
    Block 7:
        (original IR block: block6)
        (successor: Block 9)
        (instruction range: 27 .. 30)
      Inst 27: lea     -1(%v210), %v222
      Inst 28: movq    %v218, 8(%v208)
      Inst 29: jmp     label9
    Block 8:
        (original IR block: block5)
        (successor: Block 9)
        (instruction range: 30 .. 34)
      Inst 30: movq    56(%v192), %v221
      Inst 31: movq    200(%v215), %v220
      Inst 32: call    *%v216
      Inst 33: jmp     label9
    Block 9:
        (original IR block: block7)
        (successor: Block 10)
        (instruction range: 34 .. 35)
      Inst 34: jmp     label10
    Block 10:
        (original IR block: block1)
        (instruction range: 35 .. 36)
      Inst 35: rets
    Block 11:
        (original IR block: block8)
        (instruction range: 36 .. 37)
      Inst 36: ud2 table_oob
    }

Steps to Reproduce

clif-util compile --target x86_64 regalloc-error.clif

Expected Results

No compilation errors

Actual Results

thread 'main' panicked at /home/nick/.cargo/registry/src/index.crates.io-6f17d22bba15001f/regalloc2-0.9.3/src/ion/liveranges.rs:884:57:
multiple uses of vreg with a Stack constraint are not supported

cc @cfallin @elliottt any ideas what's going on here? Error message is not super helpful.


Last updated: Dec 23 2024 at 12:05 UTC