optimize the case of cond ? 42 : 41 and friends. This compiles the
authorChris Lattner <sabre@nondot.org>
Fri, 13 Mar 2009 05:22:11 +0000 (05:22 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 Mar 2009 05:22:11 +0000 (05:22 +0000)
example to:

_test:
movl 4(%esp), %eax
cmpl $41, (%eax)
setg %al
movzbl %al, %eax
orl $4294967294, %eax
ret

instead of:

        movl    4(%esp), %eax
        cmpl    $41, (%eax)
movl $4294967294, %ecx
movl $4294967295, %eax
cmova %ecx, %eax
ret

which is smaller in code size and faster. rdar://6668608

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

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/select-no-cmov.ll [new file with mode: 0644]

index dfa2a090985c2cc3d2d3006a15d1c8e5633cb537..f54b7b6f80e4dcbc539808f661381940731cdb89 100644 (file)
@@ -8218,6 +8218,18 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
           return DAG.getNode(ISD::SHL, DL, LHS.getValueType(), Cond,
                              DAG.getConstant(ShAmt, MVT::i8));
         }
+        
+        // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst.
+        if (RHSC->getAPIntValue()+1 == LHSC->getAPIntValue()) {
+          if (NeedsCondInvert) // Invert the condition if needed.
+            Cond = DAG.getNode(ISD::XOR, DL, Cond.getValueType(), Cond,
+                               DAG.getConstant(1, Cond.getValueType()));
+          
+          // Zero extend the condition if needed.
+          Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, RHSC->getValueType(0), Cond);
+          return DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond,
+                             SDValue(RHSC, 0));
+        }
       }
   }
       
@@ -8263,6 +8275,21 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG,
           return DCI.CombineTo(N, Cond, SDValue());
         return Cond;
       }
+
+      // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst.
+      if (FalseC->getAPIntValue()+1 == TrueC->getAPIntValue()) {
+        SDValue Cond = N->getOperand(3);
+        Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
+                           DAG.getConstant(CC, MVT::i8), Cond);
+        
+        // Zero extend the condition if needed.
+        Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, FalseC->getValueType(0), Cond);
+        Cond = DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond,
+                           SDValue(FalseC, 0));
+        if (N->getNumValues() == 2)  // Dead flag value?
+          return DCI.CombineTo(N, Cond, SDValue());
+        return Cond;
+      }
     }
   }
   return SDValue();
diff --git a/test/CodeGen/X86/select-no-cmov.ll b/test/CodeGen/X86/select-no-cmov.ll
new file mode 100644 (file)
index 0000000..87382fe
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc | not grep cmov
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin7"
+
+; Should compile to setcc | -2.
+; rdar://6668608
+define i32 @test(i32* nocapture %P) nounwind readonly {
+entry:
+       %0 = load i32* %P, align 4              ; <i32> [#uses=1]
+       %1 = icmp sgt i32 %0, 41                ; <i1> [#uses=1]
+       %iftmp.0.0 = select i1 %1, i32 -1, i32 -2               ; <i32> [#uses=1]
+       ret i32 %iftmp.0.0
+}