Hi Jacob,
thanks for the fast response. Could you have a quick look at the assertion I get
with r161643? Before that last commit, i.e., with r161642, everything went fine
for my backend, but after this commit, with no other changes, PHI-elimination
suddenly broke as follows:
# *** IR Dump Before Eliminate PHI nodes for register allocation ***:
# Machine code for function CGA_kernel_read: SSA
Function Live Ins: %P0 in %vreg5, %P1 in %vreg6
Function Live Outs: %P15
BB#0: derived from LLVM BB %entry
Live Ins: %P0 %P1
DBG_VALUE %P0, 0, !"buf"; line no:42
DBG_VALUE %P1, 0, !"count"; line no:42
DBG_VALUE %P0, 0, !"p"; line no:44
%vreg6<def> = COPY %P1; IntRegs:%vreg6
DBG_VALUE %vreg6, 0, !"count"; IntRegs:%vreg6 line no:42
%vreg5<def> = COPY %P0; IntRegs:%vreg5
DBG_VALUE %vreg5, 0, !"buf"; IntRegs:%vreg5 line no:42
DBG_VALUE %vreg5, 0, !"p"; IntRegs:%vreg5 line no:44
%vreg8<def> = MOV32ri <ga:@fifo>, pred:%noreg; IntRegs:%vreg8
dbg:../src/getbits.c:46:1
%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
%vreg10<def> = CMPEQI %vreg9<kill>, 0, pred:%noreg;
PredRegs:%vreg10 IntRegs:%vreg9 dbg:../src/getbits.c:46:1
JUMP <BB#2>, pred:%vreg10<kill>; PredRegs:%vreg10
Successors according to CFG: BB#2 BB#1
BB#1:
Predecessors according to CFG: BB#0
%vreg7<def> = MOV32ri -1, pred:%noreg; IntRegs:%vreg7
JUMP <BB#5>, pred:%noreg
Successors according to CFG: BB#5
BB#2: derived from LLVM BB %while.cond.preheader
Predecessors according to CFG: BB#0
%vreg11<def> = MOV32ri 0, pred:%noreg; IntRegs:%vreg11
%vreg12<def> = CMPEQI %vreg6, 0, pred:%noreg; PredRegs:%vreg12
IntRegs:%vreg6 dbg:../src/getbits.c:53:3
JUMP <BB#5>, pred:%vreg12<kill>; PredRegs:%vreg12
Successors according to CFG: BB#5 BB#3
BB#3:
Predecessors according to CFG: BB#2
Successors according to CFG: BB#4
BB#4: derived from LLVM BB %while.body
Predecessors according to CFG: BB#4 BB#3
%vreg0<def> = PHI %vreg11, <BB#3>, %vreg2, <BB#4>;
IntRegs:%vreg0,%vreg11,%vreg2
%vreg1<def> = PHI %vreg5, <BB#3>, %vreg3, <BB#4>;
IntRegs:%vreg1,%vreg5,%vreg3
%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
STBrr %vreg1, 0, %vreg14<kill>, pred:%noreg; mem:ST1[%p.04]
IntRegs:%vreg1,%vreg14 dbg:../src/getbits.c:56:5
%vreg2<def> = ADDri %vreg0<kill>, 1, pred:%noreg;
IntRegs:%vreg2,%vreg0 dbg:../src/getbits.c:55:5
DBG_VALUE %vreg2, 0, !"r"; IntRegs:%vreg2 line no:45
%vreg15<def> = CMPLT_U %vreg2, %vreg6, pred:%noreg; PredRegs:%vreg15
IntRegs:%vreg2,%vreg6 dbg:../src/getbits.c:53:3
ADJCALLSTACKDOWN 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
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
ADJCALLSTACKUP 0, 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
%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
%vreg17<def> = CMPEQANDri %vreg15<kill>, %vreg16<kill>, 0,
pred:%noreg; PredRegs:%vreg17,%vreg15 IntRegs:%vreg16 dbg:../src/getbits.c:53:3
%vreg3<def> = ADDri %vreg1<kill>, 1, pred:%noreg;
IntRegs:%vreg3,%vreg1 dbg:../src/getbits.c:56:5
DBG_VALUE %vreg3, 0, !"p"; IntRegs:%vreg3 line no:44
JUMP <BB#4>, pred:%vreg17<kill>; PredRegs:%vreg17
dbg:../src/getbits.c:53:3
JUMP <BB#5>, pred:%noreg; dbg:../src/getbits.c:53:3
Successors according to CFG: BB#4 BB#5
BB#5: derived from LLVM BB %if.end
Predecessors according to CFG: BB#2 BB#4 BB#1
%vreg4<def> = PHI %vreg7, <BB#1>, %vreg11, <BB#2>, %vreg2,
<BB#4>; IntRegs:%vreg4,%vreg7,%vreg11,%vreg2
%P15<def> = COPY %vreg4<kill>; IntRegs:%vreg4
dbg:../src/getbits.c:60:1
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/MachineOperand.h:252: bool
llvm::MachineOperand::isUse() const: Assertion `isReg() && "Wrong
MachineOperand accessor"' failed.
Using host libthread_db library
"/lib/i386-linux-gnu/libthread_db.so.1".
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=0x8c9d818 "isReg()
&& \"Wrong MachineOperand accessor\"",
file=0x8c9d7ac
"/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineOperand.h",
line=252, function=0x8c9f7c0 "bool llvm::MachineOperand::isUse()
const")
at assert.c:94
#4 0xb7cf7147 in __GI___assert_fail (assertion=0x8c9d818 "isReg()
&& \"Wrong MachineOperand accessor\"",
file=0x8c9d7ac
"/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineOperand.h",
line=252, function=0x8c9f7c0 "bool llvm::MachineOperand::isUse()
const")
at assert.c:103
#5 0x08450f78 in llvm::MachineOperand::isUse (this=0xbfffee68) at
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineOperand.h:252
#6 0x084f4039 in llvm::MachineRegisterInfo::defusechain_iterator<false,
true, false>::operator++ (this=0xbfffee50)
at /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:521
#7 0x084f3f9d in llvm::MachineRegisterInfo::defusechain_iterator<false,
true, false>::defusechain_iterator (this=0xbfffee50, op=0x9326204)
at /work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:492
#8 0x084f3c8f in llvm::MachineRegisterInfo::def_begin (this=0x931c800,
RegNo=2147483672) at
/work/llvm/trunk/llvm/include/llvm/CodeGen/MachineRegisterInfo.h:196
#9 0x0884b4f5 in llvm::MachineRegisterInfo::getVRegDef (this=0x931c800,
Reg=2147483672) at /work/llvm/trunk/llvm/lib/CodeGen/MachineRegisterInfo.cpp:201
#10 0x087ebded in llvm::LiveVariables::VarInfo::isLiveIn (this=0x932b3b8,
MBB=..., Reg=2147483672, MRI=...) at
/work/llvm/trunk/llvm/lib/CodeGen/LiveVariables.cpp:748
#11 0x087ec2dd in llvm::LiveVariables::addNewBlock (this=0x92ca380,
BB=0x931d4fc, DomBB=0x931cae4, SuccBB=0x931cbec)
at /work/llvm/trunk/llvm/lib/CodeGen/LiveVariables.cpp:820
#12 0x087f7bd6 in llvm::MachineBasicBlock::SplitCriticalEdge (this=0x931cae4,
Succ=0x931cbec, P=0x92ff5c0)
at /work/llvm/trunk/llvm/lib/CodeGen/MachineBasicBlock.cpp:699
#13 0x0887285e in (anonymous namespace)::PHIElimination::SplitPHIEdges
(this=0x92ff5c0, MF=..., MBB=..., LV=..., MLI=0x92ff138)
at /work/llvm/trunk/llvm/lib/CodeGen/PHIElimination.cpp:485
#14 0x08871264 in (anonymous namespace)::PHIElimination::runOnMachineFunction
(this=0x92ff5c0, MF=...) at
/work/llvm/trunk/llvm/lib/CodeGen/PHIElimination.cpp:124
#15 0x0881de19 in llvm::MachineFunctionPass::runOnFunction (this=0x92ff5c0,
F=...) at /work/llvm/trunk/llvm/lib/CodeGen/MachineFunctionPass.cpp:33
#16 0x08b76c96 in llvm::FPPassManager::runOnFunction (this=0x92e2bb8, F=...) at
/work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1498
#17 0x08b76e52 in llvm::FPPassManager::runOnModule (this=0x92e2bb8, M=...) at
/work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1518
#18 0x08b77130 in llvm::MPPassManager::runOnModule (this=0x92cb660, M=...) at
/work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1572
#19 0x08b775f4 in llvm::PassManagerImpl::run (this=0x92cb118, M=...) at
/work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1655
#20 0x08b77791 in llvm::PassManager::run (this=0xbffff410, M=...) at
/work/llvm/trunk/llvm/lib/VMCore/PassManager.cpp:1684
#21 0x083a44f4 in main (argc=13, argv=0xbffff594) at
/work/llvm/trunk/llvm/tools/llc/llc.cpp:553
I enabled the printing of additional debug information in PHIelimination, but
that did not produce output before the assertion got raised.
With r161642, the PHI-elimination produced this (correct) result:
BB#1:
Predecessors according to CFG: BB#0
%vreg7<def> = MOV32ri -1, pred:%noreg; IntRegs:%vreg7
%vreg27<def> = COPY %vreg7<kill>; IntRegs:%vreg27,%vreg7
JUMP <BB#5>, pred:%noreg
Successors according to CFG: BB#5
BB#2: derived from LLVM BB %while.cond.preheader
Predecessors according to CFG: BB#0
%vreg11<def> = MOV32ri 0, pred:%noreg; IntRegs:%vreg11
%vreg24<def> = CMPNEI %vreg6, 0, pred:%noreg; PredRegs:%vreg24
IntRegs:%vreg6 dbg:../src/getbits.c:53:3
%vreg12<def> = CMPEQI %vreg6, 0, pred:%noreg; PredRegs:%vreg12
IntRegs:%vreg6 dbg:../src/getbits.c:53:3
JUMP <BB#3>, pred:%vreg24; PredRegs:%vreg24
Successors according to CFG: BB#3 BB#6
BB#6:
Predecessors according to CFG: BB#2
%vreg27<def> = COPY %vreg11<kill>; IntRegs:%vreg27,%vreg11
JUMP <BB#5>, pred:%noreg
Successors according to CFG: BB#5
BB#3:
Predecessors according to CFG: BB#2
%vreg25<def> = COPY %vreg11<kill>; IntRegs:%vreg25,%vreg11
%vreg26<def> = COPY %vreg5<kill>; IntRegs:%vreg26,%vreg5
Successors according to CFG: BB#4
BB#4: derived from LLVM BB %while.body
Predecessors according to CFG: BB#4 BB#3
%vreg0<def> = COPY %vreg25<kill>; IntRegs:%vreg0,%vreg25
%vreg1<def> = COPY %vreg26<kill>; IntRegs:%vreg1,%vreg26
%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
STBrr %vreg1, 0, %vreg14<kill>, pred:%noreg; mem:ST1[%p.04]
IntRegs:%vreg1,%vreg14 dbg:../src/getbits.c:56:5
%vreg2<def> = ADDri %vreg0<kill>, 1, pred:%noreg;
IntRegs:%vreg2,%vreg0 dbg:../src/getbits.c:55:5
DBG_VALUE %vreg2, 0, !"r"; IntRegs:%vreg2 line no:45
%vreg15<def> = CMPLT_U %vreg2, %vreg6, pred:%noreg;
PredRegs:%vreg15 IntRegs:%vreg2,%vreg6 dbg:../src/getbits.c:53:3
ADJCALLSTACKDOWN 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
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
ADJCALLSTACKUP 0, 0, pred:%noreg, %SP<imp-def>, %SP<imp-use>
%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
%vreg17<def> = CMPEQANDri %vreg15<kill>, %vreg16<kill>,
0, pred:%noreg; PredRegs:%vreg17,%vreg15 IntRegs:%vreg16
dbg:../src/getbits.c:53:3
%vreg3<def> = ADDri %vreg1<kill>, 1, pred:%noreg;
IntRegs:%vreg3,%vreg1 dbg:../src/getbits.c:56:5
DBG_VALUE %vreg3, 0, !"p"; IntRegs:%vreg3 line no:44
%vreg25<def> = COPY %vreg2; IntRegs:%vreg25,%vreg2
%vreg26<def> = COPY %vreg3<kill>; IntRegs:%vreg26,%vreg3
%vreg27<def> = COPY %vreg2<kill>; IntRegs:%vreg27,%vreg2
JUMP <BB#4>, pred:%vreg17<kill>; PredRegs:%vreg17
dbg:../src/getbits.c:53:3
JUMP <BB#5>, pred:%noreg; dbg:../src/getbits.c:53:3
Successors according to CFG: BB#4 BB#5
Thanks,
Bjorn
On 18 Sep 2012, at 22:55, Jakob Stoklund Olesen wrote:
>
> On Sep 18, 2012, at 1:45 PM, Bjorn De Sutter <bjorn.desutter at
elis.ugent.be> wrote:
>
>> 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…
>
> Hi Bjorn,
>
> It looks like the linked list of operands for a register has been
corrupted. Every (non-null) register operand belongs to a doubly linked list of
MachineOperands referencing the same register.
>
> I couldn't say how those lists got corrupted based on your debug dumps.
The lists are maintained by code in MachineInstr.cpp and
MachineRegisterInfo.cpp.
>
> /jakob
>