diff options
author | Dale Johannesen <dalej@apple.com> | 2010-06-25 00:49:43 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2010-06-25 00:49:43 +0000 |
commit | 969b9fe379c333bd5065d387da7b43ed90e001de (patch) | |
tree | 32f44a51a77e81ba3cb45700baf86d1d38533d3c /lib/CodeGen | |
parent | a0ae87fd5d8dd7e1221114c80fdfd0bba6ddaf87 (diff) | |
download | external_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.cpp | 17 |
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!"); |