diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-02-10 02:20:55 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-02-10 02:20:55 +0000 |
commit | 4d96c638af0458f4de637998da942a5e166d6ea5 (patch) | |
tree | f7a1bc561f4cb31b02eea47391bfdcb6a295bae7 | |
parent | 6793c49bb4b7d20532e530404740422036d84788 (diff) | |
download | llvm-4d96c638af0458f4de637998da942a5e166d6ea5.tar.gz llvm-4d96c638af0458f4de637998da942a5e166d6ea5.tar.bz2 llvm-4d96c638af0458f4de637998da942a5e166d6ea5.tar.xz |
After 3-addressifying a two-address instruction, update the register maps; add a missing check when considering whether it's profitable to commute. rdar://8977508.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125259 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 13 | ||||
-rw-r--r-- | test/CodeGen/X86/twoaddr-lea.ll | 32 |
2 files changed, 31 insertions, 14 deletions
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index a30279d57d..b3120b8be1 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -110,7 +110,7 @@ namespace { bool ConvertInstTo3Addr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, MachineFunction::iterator &mbbi, - unsigned RegB, unsigned Dist); + unsigned RegA, unsigned RegB, unsigned Dist); typedef std::pair<std::pair<unsigned, bool>, MachineInstr*> NewKill; bool canUpdateDeletedKills(SmallVector<unsigned, 4> &Kills, @@ -550,7 +550,7 @@ TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC, unsigned FromRegC = getMappedReg(regC, SrcRegMap); unsigned ToRegB = getMappedReg(regB, DstRegMap); unsigned ToRegC = getMappedReg(regC, DstRegMap); - if (!regsAreCompatible(FromRegB, ToRegB, TRI) && + if ((FromRegB && ToRegB && !regsAreCompatible(FromRegB, ToRegB, TRI)) && ((!FromRegC && !ToRegC) || regsAreCompatible(FromRegB, ToRegC, TRI) || regsAreCompatible(FromRegC, ToRegB, TRI))) @@ -633,7 +633,8 @@ bool TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, MachineFunction::iterator &mbbi, - unsigned RegB, unsigned Dist) { + unsigned RegA, unsigned RegB, + unsigned Dist) { MachineInstr *NewMI = TII->convertToThreeAddress(mbbi, mi, LV); if (NewMI) { DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi); @@ -653,6 +654,10 @@ TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi, mi = NewMI; nmi = llvm::next(mi); } + + // Update source and destination register maps. + SrcRegMap.erase(RegA); + DstRegMap.erase(RegB); return true; } @@ -887,7 +892,7 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi, // three-address instruction. Check if it is profitable. if (!regBKilled || isProfitableToConv3Addr(regA)) { // Try to convert it. - if (ConvertInstTo3Addr(mi, nmi, mbbi, regB, Dist)) { + if (ConvertInstTo3Addr(mi, nmi, mbbi, regA, regB, Dist)) { ++NumConvertedTo3Addr; return true; // Done with this instruction. } diff --git a/test/CodeGen/X86/twoaddr-lea.ll b/test/CodeGen/X86/twoaddr-lea.ll index a245ed7caa..ec16dfe172 100644 --- a/test/CodeGen/X86/twoaddr-lea.ll +++ b/test/CodeGen/X86/twoaddr-lea.ll @@ -5,20 +5,32 @@ ;; allocator turns the shift into an LEA. This also occurs for ADD. ; Check that the shift gets turned into an LEA. -; RUN: llc < %s -march=x86 -x86-asm-syntax=intel | \ -; RUN: not grep {mov E.X, E.X} +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s -@G = external global i32 ; <i32*> [#uses=3] +@G = external global i32 -define i32 @test1(i32 %X, i32 %Y) { - %Z = add i32 %X, %Y ; <i32> [#uses=1] - volatile store i32 %Y, i32* @G +define i32 @test1(i32 %X) nounwind { +; CHECK: test1: +; CHECK-NOT: mov +; CHECK: leal 1(%rdi) + %Z = add i32 %X, 1 volatile store i32 %Z, i32* @G ret i32 %X } -define i32 @test2(i32 %X) { - %Z = add i32 %X, 1 ; <i32> [#uses=1] - volatile store i32 %Z, i32* @G - ret i32 %X +; rdar://8977508 +; The second add should not be transformed to leal nor should it be +; commutted (which would require inserting a copy). +define i32 @test2(i32 inreg %a, i32 inreg %b, i32 %c, i32 %d) nounwind { +entry: +; CHECK: test2: +; CHECK: leal +; CHECK-NOT: leal +; CHECK-NOT: mov +; CHECK-NEXT: addl +; CHECK-NEXT: ret + %add = add i32 %b, %a + %add3 = add i32 %add, %c + %add5 = add i32 %add3, %d + ret i32 %add5 } |