[LLVMdev] liveness assertion problem in llc

Bjorn De Sutter bjorn.desutter at elis.ugent.be
Tue Sep 18 13:45:44 PDT 2012


Hi,

I am working on a backend for a CGRA architecture with advanced predicate support (as on EPIC machines and as first used in the OpenIMPACT compiler). Until last month, the backend was working fine, but since the r161643 commit by stoklund, my backend doesn't work anymore. I think I noticed some related commits later on, and the assertion I get on the latest trunk (r164162) differs from what I got on r161643 (where it was the PHIelimination that failed). From the log, I have the impression that the assertion is raised on a dead instruction during the spill weight calculation. The dead instruction (definition of vreg12 in the log below) is an instruction I add during if-conversion for use in a later pass. Previously, such dead instructions did not cause any problem...

Any idea what might be going wrong here? I've noticed that there is now something like a flag that needs to be set by code transformations that destroy existing liveness information. Maybe I should set that flag during if-conversion? Apart from that, I have no clue...

Here is the end of a log I get under gdb (gdb used for getting a more informative backtrace):

# *** IR Dump Before Calculate spill weights ***:
# Machine code for function CGA_kernel_read: Post SSA
Function Live Ins: %P0 in %vreg5, %P1 in %vreg6
Function Live Outs: %P15

0B	BB#0: derived from LLVM BB %entry
	    Live Ins: %P0 %P1
16B		%vreg6<def> = COPY %P1; IntRegs:%vreg6
48B		%vreg8<def> = MOV32ri <ga:@fifo>, pred:%noreg; IntRegs:%vreg8 dbg:../src/getbits.c:46:1
64B		%vreg9<def> = LDUBri %vreg8, 1, pred:%noreg; mem:LD1[getelementptr inbounds (%struct.FIFO* @fifo, i32 0, i32 1)] IntRegs:%vreg9,%vreg8 dbg:../src/getbits.c:46:1
80B		%vreg10<def> = CMPEQI %vreg9<kill>, 0, pred:%noreg; PredRegs:%vreg10 IntRegs:%vreg9 dbg:../src/getbits.c:46:1
96B		JUMP <BB#2>, pred:%vreg10<kill>; PredRegs:%vreg10
	    Successors according to CFG: BB#2(12) BB#1(20)

112B	BB#1: 
	    Predecessors according to CFG: BB#0
128B		%vreg27<def> = MOV32ri -1, pred:%noreg; IntRegs:%vreg27
160B		JUMP <BB#5>, pred:%noreg
	    Successors according to CFG: BB#5

176B	BB#2: derived from LLVM BB %while.cond.preheader
	    Predecessors according to CFG: BB#0
192B		%vreg27<def> = MOV32ri 0, pred:%noreg; IntRegs:%vreg27
208B		%vreg24<def> = CMPNEI %vreg6, 0, pred:%noreg; PredRegs:%vreg24 IntRegs:%vreg6 dbg:../src/getbits.c:53:3
224B		%vreg12<def> = CMPEQI %vreg6, 0, pred:%noreg; PredRegs:%vreg12 IntRegs:%vreg6 dbg:../src/getbits.c:53:3    <---- THIS IS THE DEAD INSTRUCTION
240B		JUMP <BB#3>, pred:%vreg24; PredRegs:%vreg24
	    Successors according to CFG: BB#6(12) BB#3(20)

256B	BB#6: 
	    Predecessors according to CFG: BB#2
288B		JUMP <BB#5>, pred:%noreg
	    Successors according to CFG: BB#5

304B	BB#3: 
	    Predecessors according to CFG: BB#2
336B		%vreg26<def> = COPY %P0; IntRegs:%vreg26
	    Successors according to CFG: BB#4

352B	BB#4: derived from LLVM BB %while.body
	    Predecessors according to CFG: BB#4 BB#3
400B		%vreg14<def> = LDUBrr %vreg8, 0, pred:%noreg; mem:LD1[getelementptr inbounds (%struct.FIFO* @fifo, i32 0, i32 0)] IntRegs:%vreg14,%vreg8 dbg:../src/getbits.c:56:5
416B		STBrr %vreg26, 0, %vreg14<kill>, pred:%noreg; mem:ST1[%p.04] IntRegs:%vreg26,%vreg14 dbg:../src/getbits.c:56:5
432B		%vreg27<def> = ADDri %vreg27<kill>, 1, pred:%noreg; IntRegs:%vreg27 dbg:../src/getbits.c:55:5
448B		%vreg17<def> = CMPLT_U %vreg27, %vreg6, pred:%noreg; PredRegs:%vreg17 IntRegs:%vreg27,%vreg6 dbg:../src/getbits.c:53:3
464B		ADJCALLSTACKDOWN 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
480B		CALL <ga:@CGA_kernel_advance>, 0, 0, pred:%noreg, 0, %noreg, %P0<imp-def>, %P1<imp-def>, %P2<imp-def>, %P3<imp-def>, %P15<imp-def>, %RT<imp-def>, %P0<imp-use>, %P1<imp-use>, %P2<imp-use>, %P3<imp-use>; dbg:../src/getbits.c:57:5
496B		ADJCALLSTACKUP 0, 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
512B		%vreg16<def> = LDUBri %vreg8, 1, pred:%noreg; mem:LD1[getelementptr inbounds (%struct.FIFO* @fifo, i32 0, i32 1)] IntRegs:%vreg16,%vreg8 dbg:../src/getbits.c:53:3
544B		%vreg17<def,tied1> = CMPEQANDri %vreg17<tied0>, %vreg16<kill>, 0, pred:%noreg; PredRegs:%vreg17 IntRegs:%vreg16 dbg:../src/getbits.c:53:3
560B		%vreg26<def> = ADDri %vreg26<kill>, 1, pred:%noreg; IntRegs:%vreg26 dbg:../src/getbits.c:56:5
624B		JUMP <BB#4>, pred:%vreg17<kill>; PredRegs:%vreg17 dbg:../src/getbits.c:53:3
640B		JUMP <BB#5>, pred:%noreg; dbg:../src/getbits.c:53:3
	    Successors according to CFG: BB#4(124) BB#5(4)

656B	BB#5: derived from LLVM BB %if.end
	    Predecessors according to CFG: BB#4 BB#1 BB#6
688B		%P15<def> = COPY %vreg27<kill>; IntRegs:%vreg27 dbg:../src/getbits.c:60:1
704B		RET pred:%noreg, %RT<imp-use>, %P15<imp-use,kill>; dbg:../src/getbits.c:60:1

# End machine code for function CGA_kernel_read.

llc: /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:76: static llvm::MachineOperand* llvm::MachineRegisterInfo::getNextOperandForReg(const llvm::MachineOperand*): Assertion `MO && MO->isReg() && "This is not a register operand!"' failed.

Program received signal SIGABRT, Aborted.
0xb7fdd424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7fdd424 in __kernel_vsyscall ()
#1  0xb7cfe1ef in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xb7d01835 in __GI_abort () at abort.c:91
#3  0xb7cf7095 in __assert_fail_base (fmt=0xb7e308b8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x8d27b14 "MO && MO->isReg() && \"This is not a register operand!\"", 
    file=0x8d27ad0 "/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h", line=76, 
    function=0x8d2b600 "static llvm::MachineOperand* llvm::MachineRegisterInfo::getNextOperandForReg(const llvm::MachineOperand*)") at assert.c:94
#4  0xb7cf7147 in __GI___assert_fail (assertion=0x8d27b14 "MO && MO->isReg() && \"This is not a register operand!\"", file=0x8d27ad0 "/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h", 
    line=76, function=0x8d2b600 "static llvm::MachineOperand* llvm::MachineRegisterInfo::getNextOperandForReg(const llvm::MachineOperand*)") at assert.c:103
#5  0x084faa91 in llvm::MachineRegisterInfo::getNextOperandForReg (MO=0xbfffee8c) at /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:76
#6  0x086a8118 in llvm::MachineRegisterInfo::defusechain_iterator<true, true, false>::operator++ (this=0xbffff068) at /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:514
#7  0x08803f51 in llvm::MachineRegisterInfo::defusechain_iterator<true, true, false>::skipInstruction (this=0xbffff068) at /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:543
#8  0x0896d5bf in llvm::VirtRegAuxInfo::CalculateWeightAndHint (this=0xbffff0d8, li=...) at /work/llvm/trunk/llvm/lib/CodeGen/CalcSpillWeights.cpp:131
#9  0x0896d22e in llvm::CalculateSpillWeights::runOnMachineFunction (this=0x937f0a8, MF=...) at /work/llvm/trunk/llvm/lib/CodeGen/CalcSpillWeights.cpp:53
#10 0x08847e95 in llvm::MachineFunctionPass::runOnFunction (this=0x937f0a8, F=...) at /work/llvm/trunk/llvm/lib/CodeGen/MachineFunctionPass.cpp:33
#11 0x08bcdbec in llvm::FPPassManager::runOnFunction (this=0x9348038, F=...) at /work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1498
#12 0x08bcdda8 in llvm::FPPassManager::runOnModule (this=0x9348038, M=...) at /work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1518
#13 0x08bce086 in llvm::MPPassManager::runOnModule (this=0x9347130, M=...) at /work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1572
#14 0x08bce578 in llvm::PassManagerImpl::run (this=0x9347690, M=...) at /work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1655
#15 0x08bce715 in llvm::PassManager::run (this=0xbffff400, M=...) at /work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1684
#16 0x083ad0a6 in main (argc=13, argv=0xbffff584) at /work/llvm/trunk/llvm/tools/llc/llc.cpp:559
(gdb) 

By the way, when I try to add a pass before register allocation to remove the inserted dead instruction with the following code, I get a similar assertion on the MRI.use_empty. This code also used to work until before r161643.

bool ADRESUselessPredicateCleanup::eliminateUselessPredicate(MachineInstr *MI){
  
  // find destination operand and check it is a register
  MachineOperand MO = MI->getOperand(0);
  if (!MO.isReg()) return false;
  
  unsigned reg = MO.getReg();
  MachineRegisterInfo &MRI=MI->getParent()->getParent()->getRegInfo();

  //  MI->dump();

  // if the produced register is not used anywhere in the method and it is a predicate register
  // eliminate the instruction
  // TODO: fix the ugly check for PredicateRegisters
  if (MRI.use_empty(reg)) {
    if ( !TargetRegisterInfo::isPhysicalRegister(reg) || (reg >= ADRES::p0 && reg <= ADRES::p387)) {
      MI->eraseFromParent();
      return true;
    } 
  }
  return false;
}

Thanks a lot,

Bjorn De Sutter
Computer Systems Lab
Ghent University








More information about the llvm-dev mailing list