summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-09-24 02:27:09 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-09-24 02:27:09 +0000
commit393e277ecd02f52443633f6bfacdd1d4c6981212 (patch)
tree3a4869f278ff2387db23b9757497a286973f743b
parentad934b821c78d39e73a213c62cd57288f8605a0c (diff)
downloadllvm-393e277ecd02f52443633f6bfacdd1d4c6981212.tar.gz
llvm-393e277ecd02f52443633f6bfacdd1d4c6981212.tar.bz2
llvm-393e277ecd02f52443633f6bfacdd1d4c6981212.tar.xz
Fix PR5024 with a big hammer: disable the double-def assertion in the scavenger.
LiveVariables add implicit kills to correctly track partial register kills. This works well enough and is fairly accurate. But coalescer can make it impossible to maintain these markers. e.g. BL <ga:sss1>, %R0<kill,undef>, %S0<kill>, %R0<imp-def>, %R1<imp-def,dead>, %R2<imp-def,dead>, %R3<imp-def,dead>, %R12<imp-def,dead>, %LR<imp-def,dead>, %D0<imp-def>, ... ... %reg1031<def> = FLDS <cp#1>, 0, 14, %reg0, Mem:LD4[ConstantPool] ... %S0<def> = FCPYS %reg1031<kill>, 14, %reg0, %D0<imp-use,kill> When reg1031 and S0 are coalesced, the copy (FCPYS) will be eliminated the the implicit-kill of D0 is lost. In this case it's possible to move the marker to the FLDS. But in many cases, this is not possible. Suppose %reg1031<def> = FOO <cp#1>, %D0<imp-def> ... %S0<def> = FCPYS %reg1031<kill>, 14, %reg0, %D0<imp-use,kill> When FCPYS goes away, the definition of S0 is the "FOO" instruction. However, transferring the D0 implicit-kill to FOO doesn't work since it is the def of D0 itself. We need to fix this in another time by introducing a "kill" pseudo instruction to track liveness. Disabling the assertion is not ideal, but machine verifier is doing that job now. It's important to know double-def is not a miscomputation since it means a register should be free but it's not tracked as free. It's a performance issue instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82677 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp43
-rw-r--r--test/CodeGen/ARM/2009-09-23-LiveVariablesBug.ll21
2 files changed, 25 insertions, 39 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 29628f1012..f878eaa55e 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -109,45 +109,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
Tracking = false;
}
-#ifndef NDEBUG
-/// isLiveInButUnusedBefore - Return true if register is livein the MBB not
-/// not used before it reaches the MI that defines register.
-static bool isLiveInButUnusedBefore(unsigned Reg, MachineInstr *MI,
- MachineBasicBlock *MBB,
- const TargetRegisterInfo *TRI,
- MachineRegisterInfo* MRI) {
- // First check if register is livein.
- bool isLiveIn = false;
- for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(),
- E = MBB->livein_end(); I != E; ++I)
- if (Reg == *I || TRI->isSuperRegister(Reg, *I)) {
- isLiveIn = true;
- break;
- }
- if (!isLiveIn)
- return false;
-
- // Is there any use of it before the specified MI?
- SmallPtrSet<MachineInstr*, 4> UsesInMBB;
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
- UE = MRI->use_end(); UI != UE; ++UI) {
- MachineOperand &UseMO = UI.getOperand();
- if (UseMO.isReg() && UseMO.isUndef())
- continue;
- MachineInstr *UseMI = &*UI;
- if (UseMI->getParent() == MBB)
- UsesInMBB.insert(UseMI);
- }
- if (UsesInMBB.empty())
- return true;
-
- for (MachineBasicBlock::iterator I = MBB->begin(), E = MI; I != E; ++I)
- if (UsesInMBB.count(&*I))
- return false;
- return true;
-}
-#endif
-
void RegScavenger::addRegWithSubRegs(BitVector &BV, unsigned Reg) {
BV.set(Reg);
for (const unsigned *R = TRI->getSubRegisters(Reg); *R; R++)
@@ -221,9 +182,13 @@ void RegScavenger::forward() {
"Using an early clobbered register!");
} else {
assert(MO.isDef());
+#if 0
+ // FIXME: Enable this once we've figured out how to correctly transfer
+ // implicit kills during codegen passes like the coalescer.
assert((KillRegs.test(Reg) || isUnused(Reg) ||
isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
"Re-defining a live register!");
+#endif
}
}
diff --git a/test/CodeGen/ARM/2009-09-23-LiveVariablesBug.ll b/test/CodeGen/ARM/2009-09-23-LiveVariablesBug.ll
new file mode 100644
index 0000000000..2ff479b217
--- /dev/null
+++ b/test/CodeGen/ARM/2009-09-23-LiveVariablesBug.ll
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mattr=+neon
+
+; PR5024
+
+%struct.1 = type { %struct.4, %struct.4 }
+%struct.4 = type { <4 x float> }
+
+define arm_aapcs_vfpcc %struct.1* @hhh3(%struct.1* %this, <4 x float> %lenation.0, <4 x float> %legalation.0) nounwind {
+entry:
+ %0 = call arm_aapcs_vfpcc %struct.4* @sss1(%struct.4* undef, float 0.000000e+00) nounwind ; <%struct.4*> [#uses=0]
+ %1 = call arm_aapcs_vfpcc %struct.4* @qqq1(%struct.4* null, float 5.000000e-01) nounwind ; <%struct.4*> [#uses=0]
+ %val92 = load <4 x float>* null ; <<4 x float>> [#uses=1]
+ %2 = call arm_aapcs_vfpcc %struct.4* @zzz2(%struct.4* undef, <4 x float> %val92) nounwind ; <%struct.4*> [#uses=0]
+ ret %struct.1* %this
+}
+
+declare arm_aapcs_vfpcc %struct.4* @qqq1(%struct.4*, float) nounwind
+
+declare arm_aapcs_vfpcc %struct.4* @sss1(%struct.4*, float) nounwind
+
+declare arm_aapcs_vfpcc %struct.4* @zzz2(%struct.4*, <4 x float>) nounwind