Fix two-address pass's aggressive instruction commuting heuristics. It's meant
authorEvan Cheng <evan.cheng@apple.com>
Thu, 3 May 2012 01:45:13 +0000 (01:45 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 3 May 2012 01:45:13 +0000 (01:45 +0000)
to catch cases like:
 %reg1024<def> = MOV r1
 %reg1025<def> = MOV r0
 %reg1026<def> = ADD %reg1024, %reg1025
 r0            = MOV %reg1026

By commuting ADD, it let coalescer eliminate all of the copies. However, there
was a bug in the heuristics where it ended up commuting the ADD in:

 %reg1024<def> = MOV r0
 %reg1025<def> = MOV 0
 %reg1026<def> = ADD %reg1024, %reg1025
 r0            = MOV %reg1026

That did no benefit but rather ensure the last MOV would not be coalesced.

rdar://11355268

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156048 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TwoAddressInstructionPass.cpp
test/CodeGen/X86/4char-promote.ll
test/CodeGen/X86/jump_sign.ll

index f98e059ed83c0bd435356761aad1611a7880434c..1277df3dc70f263f904bf807fdfcf1671076238b 100644 (file)
@@ -102,7 +102,7 @@ namespace {
     MachineInstr *FindLastUseInMBB(unsigned Reg, MachineBasicBlock *MBB,
                                    unsigned Dist);
 
-    bool isProfitableToCommute(unsigned regB, unsigned regC,
+    bool isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC,
                                MachineInstr *MI, MachineBasicBlock *MBB,
                                unsigned Dist);
 
@@ -567,7 +567,8 @@ regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) {
 /// isProfitableToReMat - Return true if it's potentially profitable to commute
 /// the two-address instruction that's being processed.
 bool
-TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC,
+TwoAddressInstructionPass::isProfitableToCommute(unsigned regA, unsigned regB,
+                                       unsigned regC,
                                        MachineInstr *MI, MachineBasicBlock *MBB,
                                        unsigned Dist) {
   if (OptLevel == CodeGenOpt::None)
@@ -604,15 +605,15 @@ TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC,
   // %reg1026<def> = ADD %reg1024, %reg1025
   // r0            = MOV %reg1026
   // Commute the ADD to hopefully eliminate an otherwise unavoidable copy.
-  unsigned FromRegB = getMappedReg(regB, SrcRegMap);
-  unsigned FromRegC = getMappedReg(regC, SrcRegMap);
-  unsigned ToRegB = getMappedReg(regB, DstRegMap);
-  unsigned ToRegC = getMappedReg(regC, DstRegMap);
-  if ((FromRegB && ToRegB && !regsAreCompatible(FromRegB, ToRegB, TRI)) &&
-      ((!FromRegC && !ToRegC) ||
-       regsAreCompatible(FromRegB, ToRegC, TRI) ||
-       regsAreCompatible(FromRegC, ToRegB, TRI)))
-    return true;
+  unsigned ToRegA = getMappedReg(regA, DstRegMap);
+  if (ToRegA) {
+    unsigned FromRegB = getMappedReg(regB, SrcRegMap);
+    unsigned FromRegC = getMappedReg(regC, SrcRegMap);
+    bool BComp = !FromRegB || regsAreCompatible(FromRegB, ToRegA, TRI);
+    bool CComp = !FromRegC || regsAreCompatible(FromRegC, ToRegA, TRI);
+    if (BComp != CComp)
+      return !BComp && CComp;
+  }
 
   // If there is a use of regC between its last def (could be livein) and this
   // instruction, then bail.
@@ -1211,6 +1212,9 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi,
     return true; // Done with this instruction.
   }
 
+  if (TargetRegisterInfo::isVirtualRegister(regA))
+    ScanUses(regA, &*mbbi, Processed);
+
   // Check if it is profitable to commute the operands.
   unsigned SrcOp1, SrcOp2;
   unsigned regC = 0;
@@ -1230,7 +1234,7 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi,
         // If C dies but B does not, swap the B and C operands.
         // This makes the live ranges of A and C joinable.
         TryCommute = true;
-      else if (isProfitableToCommute(regB, regC, &MI, mbbi, Dist)) {
+      else if (isProfitableToCommute(regA, regB, regC, &MI, mbbi, Dist)) {
         TryCommute = true;
         AggressiveCommute = true;
       }
@@ -1252,9 +1256,6 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi,
     return true;
   }
 
-  if (TargetRegisterInfo::isVirtualRegister(regA))
-    ScanUses(regA, &*mbbi, Processed);
-
   if (MI.isConvertibleTo3Addr()) {
     // This instruction is potentially convertible to a true
     // three-address instruction.  Check if it is profitable.
index 386057f0a3b68af7b79404c04b0e8a615d34c22c..6d7bc0cc7025e71e4013048c7f4c258c1aacf6db 100644 (file)
@@ -1,11 +1,12 @@
 ; A test for checking PR 9623
-;RUN: llc -march=x86-64 -mcpu=corei7 -promote-elements < %s | FileCheck %s
+; RUN: llc -march=x86-64 -mcpu=corei7 -promote-elements < %s | FileCheck %s
 
 target triple = "x86_64-apple-darwin"
 
 ; CHECK:  pmulld 
 ; CHECK:  paddd  
-; CHECK:  movdqa 
+; CHECK-NOT:  movdqa 
+; CHECK:  ret
 
 define <4 x i8> @foo(<4 x i8> %x, <4 x i8> %y) {
 entry:
index 35f69c95683891689a42f7ecf68bd2243fda10a3..94cbe5d1937c4437369471336cb30a30b567965b 100644 (file)
@@ -22,6 +22,7 @@ declare i32 @bar(...)
 declare i32 @baz(...)
 
 ; rdar://10633221
+; rdar://11355268
 define i32 @g(i32 %a, i32 %b) nounwind {
 entry:
 ; CHECK: g:
@@ -39,6 +40,8 @@ entry:
 ; CHECK: h:
 ; CHECK-NOT: cmp
 ; CHECK: cmov
+; CHECK-NOT: movl
+; CHECK: ret
   %cmp = icmp slt i32 %b, %a
   %sub = sub nsw i32 %a, %b
   %cond = select i1 %cmp, i32 %sub, i32 0
@@ -49,6 +52,8 @@ entry:
 ; CHECK: i:
 ; CHECK-NOT: cmp
 ; CHECK: cmov
+; CHECK-NOT: movl
+; CHECK: ret
   %cmp = icmp sgt i32 %a, %b
   %sub = sub nsw i32 %a, %b
   %cond = select i1 %cmp, i32 %sub, i32 0
@@ -59,6 +64,8 @@ entry:
 ; CHECK: j:
 ; CHECK-NOT: cmp
 ; CHECK: cmov
+; CHECK-NOT: movl
+; CHECK: ret
   %cmp = icmp ugt i32 %a, %b
   %sub = sub i32 %a, %b
   %cond = select i1 %cmp, i32 %sub, i32 0
@@ -69,6 +76,8 @@ entry:
 ; CHECK: k:
 ; CHECK-NOT: cmp
 ; CHECK: cmov
+; CHECK-NOT: movl
+; CHECK: ret
   %cmp = icmp ult i32 %b, %a
   %sub = sub i32 %a, %b
   %cond = select i1 %cmp, i32 %sub, i32 0