Error at Pre-regalloc Machine LICM: "getVRegDef assumes a single definition or no definition"' failed.

Hello.
     Does anybody have an idea why I'm getting the error below when using llc with arguments -O1 -disable-cgp? Note that this error is not given when using llc -O0. (I'd like to mention also I'm using custom Instruction selection for BUILD_VECTOR, which gets converted in my back end's machine instrution VLOAD_D, although the custom code seems to always select instructions in a valid way.)

     ******** Pre-regalloc Machine LICM: Test ********
     Entering BB#4
     Hoist non-reg-pressure: %vreg50<def> = VLOAD_D 1; MSA128D:%vreg50 dbg:IfVectorize.c:37:16
     Hoisting %vreg50<def> = VLOAD_D 1; MSA128D:%vreg50 dbg:IfVectorize.c:37:16
      from BB#4 to BB#3
     Hoist non-reg-pressure: %vreg51<def> = VLOAD_D 0; MSA128D:%vreg51
     Hoisting %vreg51<def> = VLOAD_D 0; MSA128D:%vreg51
      from BB#4 to BB#3
     Can't remat / high reg-pressure: %vreg54<def> = COPY %vreg50; BoolMask:%vreg54 MSA128D:%vreg50 dbg:IfVectorize.c:37:16
     Can't remat / high reg-pressure: %vreg57<def> = COPY %vreg50; BoolMask:%vreg57 MSA128D:%vreg50 dbg:IfVectorize.c:37:16
     Entering BB#15
     Hoisting %vreg66<def> = LD_imm64 4294967296; GPR:%vreg66
      from BB#15 to BB#6
     Entering BB#12
     Hoist non-reg-pressure: %vreg83<def> = VLOAD_D 3; MSA128D:%vreg83 dbg:IfVectorize.c:42:13
     Hoisting %vreg83<def> = VLOAD_D 3; MSA128D:%vreg83 dbg:IfVectorize.c:42:13
      from BB#12 to BB#11
     Hoist non-reg-pressure: %vreg84<def> = ORV_D %vreg83, %vreg83; MSA128D:%vreg84,%vreg83,%vreg83 dbg:IfVectorize.c:42:18
     Hoisting %vreg84<def> = ORV_D %vreg83, %vreg83; MSA128D:%vreg84,%vreg83,%vreg83 dbg:IfVectorize.c:42:18
      from BB#12 to BB#11
     Hoist non-reg-pressure: %vreg86<def> = VLOAD_D 1; MSA128D:%vreg86 dbg:IfVectorize.c:42:13
     Hoisting %vreg86<def> = VLOAD_D 1; MSA128D:%vreg86 dbg:IfVectorize.c:42:13
      from BB#12 to BB#11
     Hoist non-reg-pressure: %vreg87<def> = VLOAD_D 0; MSA128D:%vreg87 dbg:IfVectorize.c:42:18
     Hoisting %vreg87<def> = VLOAD_D 0; MSA128D:%vreg87 dbg:IfVectorize.c:42:18
      from BB#12 to BB#11
     Hoist non-reg-pressure: %vreg85<def> = VLOAD_D 101; MSA128D:%vreg85 dbg:IfVectorize.c:42:13
     Hoisting %vreg85<def> = VLOAD_D 101; MSA128D:%vreg85 dbg:IfVectorize.c:42:13
      from BB#12 to BB#11
     Hoist non-reg-pressure: %vreg84<def> = ORV_D %vreg85, %vreg85; MSA128D:%vreg84,%vreg85,%vreg85 dbg:IfVectorize.c:42:18
     Hoisting %vreg84<def> = ORV_D %vreg85, %vreg85; MSA128D:%vreg84,%vreg85,%vreg85 dbg:IfVectorize.c:42:18
      from BB#12 to BB#11
     Can't remat / high reg-pressure: %vreg94<def> = COPY %vreg86; BoolMask:%vreg94 MSA128D:%vreg86 dbg:IfVectorize.c:42:13

     llc: /llvm/lib/CodeGen/MachineRegisterInfo.cpp:339: llvm::MachineInstr* llvm::MachineRegisterInfo::getVRegDef(unsigned int) const: Assertion `(I.atEnd() || std::next(I) == def_instr_end()) && "getVRegDef assumes a single definition or no definition"' failed.

     0 libLLVMSupport.so 0x00007f634e255700 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 72
     1 libLLVMSupport.so 0x00007f634e255a9a
     2 libLLVMSupport.so 0x00007f634e253b55 llvm::sys::RunSignalHandlers() + 133
     3 libLLVMSupport.so 0x00007f634e254f4b
     4 libc.so.6 0x00007f634d1054b0
     5 libc.so.6 0x00007f634d105428 gsignal + 56
     6 libc.so.6 0x00007f634d10702a abort + 362
     7 libc.so.6 0x00007f634d0fdbd7
     8 libc.so.6 0x00007f634d0fdc82
     9 libLLVMCodeGen.so 0x00007f6350b39ef2 llvm::MachineRegisterInfo::getVRegDef(unsigned int) const + 182
     10 libLLVMCodeGen.so 0x00007f6350afd238
     11 libLLVMCodeGen.so 0x00007f6350aff75f
     12 libLLVMCodeGen.so 0x00007f6350afbef5
     13 libLLVMCodeGen.so 0x00007f6350afa279
     14 libLLVMCodeGen.so 0x00007f6350ae5d3a llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 426
     15 libLLVMCore.so 0x00007f635000f035 llvm::FPPassManager::runOnFunction(llvm::Function&) + 305
     16 libLLVMCore.so 0x00007f635000f1ec llvm::FPPassManager::runOnModule(llvm::Module&) + 112
     17 libLLVMCore.so 0x00007f635000f5a9
     18 libLLVMCore.so 0x00007f635000fd13 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 259
     19 libLLVMCore.so 0x00007f635000ff53 llvm::legacy::PassManager::run(llvm::Module&) + 39
     20 llc 0x000000000042f134
     21 llc 0x000000000042dacc main + 359
     22 libc.so.6 0x00007f634d0f0830 __libc_start_main + 240
     23 llc 0x000000000042be09 _start + 41
     Stack dump:
     0. Program arguments: /llvm/build40/bin/llc -print-after-all -debug -march=connex -O1 -disable-cgp -post-RA-scheduler -enable-asm-printAlex -asm-show-inst -asm-verbose -debug-pass=Structure IfVectorize.ll
     1. Running pass 'Function Pass Manager' on module 'IfVectorize.ll'.
     2. Running pass 'Machine Loop Invariant Code Motion' on function '@Test'

   Thank you very much.
     Alex

The immediate explanation of what this means if pretty easy: virtual registers are SSA (like values in LLVM IR), so every virtual register should have exactly one definition.

You might want to try the "-verify-machineinstrs" flag to llc to get better error messages for mistakes like this.

-Eli

Hello.
Does anybody have an idea why I’m getting the error below when using llc with arguments -O1 -disable-cgp? Note that this error is not given when using llc -O0. (I’d like to mention also I’m using custom Instruction selection for BUILD_VECTOR, which gets converted in my back end’s machine instrution VLOAD_D, although the custom code seems to always select instructions in a valid way.)

******** Pre-regalloc Machine LICM: Test ********
Entering BB#4
Hoist non-reg-pressure: %vreg50 = VLOAD_D 1; MSA128D:%vreg50 dbg:IfVectorize.c:37:16
Hoisting %vreg50 = VLOAD_D 1; MSA128D:%vreg50 dbg:IfVectorize.c:37:16
from BB#4 to BB#3
Hoist non-reg-pressure: %vreg51 = VLOAD_D 0; MSA128D:%vreg51
Hoisting %vreg51 = VLOAD_D 0; MSA128D:%vreg51
from BB#4 to BB#3
Can’t remat / high reg-pressure: %vreg54 = COPY %vreg50; BoolMask:%vreg54 MSA128D:%vreg50 dbg:IfVectorize.c:37:16
Can’t remat / high reg-pressure: %vreg57 = COPY %vreg50; BoolMask:%vreg57 MSA128D:%vreg50 dbg:IfVectorize.c:37:16
Entering BB#15
Hoisting %vreg66 = LD_imm64 4294967296; GPR:%vreg66
from BB#15 to BB#6
Entering BB#12
Hoist non-reg-pressure: %vreg83 = VLOAD_D 3; MSA128D:%vreg83 dbg:IfVectorize.c:42:13
Hoisting %vreg83 = VLOAD_D 3; MSA128D:%vreg83 dbg:IfVectorize.c:42:13
from BB#12 to BB#11
Hoist non-reg-pressure: %vreg84 = ORV_D %vreg83, %vreg83; MSA128D:%vreg84,%vreg83,%vreg83 dbg:IfVectorize.c:42:18
Hoisting %vreg84 = ORV_D %vreg83, %vreg83; MSA128D:%vreg84,%vreg83,%vreg83 dbg:IfVectorize.c:42:18
from BB#12 to BB#11
Hoist non-reg-pressure: %vreg86 = VLOAD_D 1; MSA128D:%vreg86 dbg:IfVectorize.c:42:13
Hoisting %vreg86 = VLOAD_D 1; MSA128D:%vreg86 dbg:IfVectorize.c:42:13
from BB#12 to BB#11
Hoist non-reg-pressure: %vreg87 = VLOAD_D 0; MSA128D:%vreg87 dbg:IfVectorize.c:42:18
Hoisting %vreg87 = VLOAD_D 0; MSA128D:%vreg87 dbg:IfVectorize.c:42:18
from BB#12 to BB#11
Hoist non-reg-pressure: %vreg85 = VLOAD_D 101; MSA128D:%vreg85 dbg:IfVectorize.c:42:13
Hoisting %vreg85 = VLOAD_D 101; MSA128D:%vreg85 dbg:IfVectorize.c:42:13
from BB#12 to BB#11
Hoist non-reg-pressure: %vreg84 = ORV_D %vreg85, %vreg85; MSA128D:%vreg84,%vreg85,%vreg85 dbg:IfVectorize.c:42:18
Hoisting %vreg84 = ORV_D %vreg85, %vreg85; MSA128D:%vreg84,%vreg85,%vreg85 dbg:IfVectorize.c:42:18
from BB#12 to BB#11
Can’t remat / high reg-pressure: %vreg94 = COPY %vreg86; BoolMask:%vreg94 MSA128D:%vreg86 dbg:IfVectorize.c:42:13

llc: /llvm/lib/CodeGen/MachineRegisterInfo.cpp:339: llvm::MachineInstr* llvm::MachineRegisterInfo::getVRegDef(unsigned int) const: Assertion `(I.atEnd() || std::next(I) == def_instr_end()) && “getVRegDef assumes a single definition or no definition”’ failed.

The immediate explanation of what this means if pretty easy: virtual registers are SSA (like values in LLVM IR), so every virtual register should have exactly one definition.

Just to be more exact here:

virtual registers must be in SSA form as long as MachineRegisterInfo::isSSA() says so. In practice the PhiElimination and the TwoAddressInstruction passes destruct SSA form and clear this flag. Afterwards virtual registers may have multiple definitions (for example to model two address instructions or to have copies in multiple predecessor block where we had a phi before).

Note though that even when the program is not in SSA form anymore we have some rules that vreg liveness must be continuos/connected. So a sequence of 4 instructions like “v0 = def; use v0; v0 = def; use v0” would be invalid as it would produce two disconnected live intervals which means that we could trivially rename half of the uses in the example to something like v1 and remove an unnecessary constraint on the register allocator.

  • Matthias