aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2010-06-25 00:49:43 +0000
committerDale Johannesen <dalej@apple.com>2010-06-25 00:49:43 +0000
commit969b9fe379c333bd5065d387da7b43ed90e001de (patch)
tree32f44a51a77e81ba3cb45700baf86d1d38533d3c /lib/CodeGen
parenta0ae87fd5d8dd7e1221114c80fdfd0bba6ddaf87 (diff)
downloadexternal_llvm-969b9fe379c333bd5065d387da7b43ed90e001de.zip
external_llvm-969b9fe379c333bd5065d387da7b43ed90e001de.tar.gz
external_llvm-969b9fe379c333bd5065d387da7b43ed90e001de.tar.bz2
Fix a case where an earlyclobber operand of an asm
is reused as an input. PR 4118. Testcase is too big, as usual with bugs in this area, but there's one in the PR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106816 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index 361d35e..6370d8f 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -2033,6 +2033,21 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
CanReuse = !ReusedOperands.isClobbered(PhysReg) &&
Spills.canClobberPhysReg(PhysReg);
}
+ // If this is an asm, and PhysReg is used elsewhere as an earlyclobber
+ // operand, we can't also use it as an input. (Outputs always come
+ // before inputs, so we can stop looking at i.)
+ if (MI.getOpcode()==TargetOpcode::INLINEASM) {
+ for (unsigned k=0; k<i; ++k) {
+ MachineOperand &MOk = MI.getOperand(k);
+ if (!MOk.isReg() || MOk.getReg()==0)
+ continue;
+ unsigned VirtRegk = MOk.getReg();
+ if (VirtRegk == PhysReg && MOk.isEarlyClobber()) {
+ CanReuse = false;
+ break;
+ }
+ }
+ }
if (CanReuse) {
// If this stack slot value is already available, reuse it!
@@ -2103,6 +2118,8 @@ LocalRewriter::RewriteMBB(LiveIntervals *LIs,
// To avoid this problem, and to avoid doing a load right after a store,
// we emit a copy from PhysReg into the designated register for this
// operand.
+ //
+ // This case also applies to an earlyclobber'd PhysReg.
unsigned DesignatedReg = VRM->getPhys(VirtReg);
assert(DesignatedReg && "Must map virtreg to physreg!");