generalize the previous check to handle -1 on either side of the
authorChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2010 02:00:51 +0000 (02:00 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2010 02:00:51 +0000 (02:00 +0000)
select, inserting a not to compensate.  Add a missing isZero check
that I lost somehow.

This improves codegen of:

void *func(long count) {
      return new int[count];
}

from:

__Z4funcl:                              ## @_Z4funcl
movl $4, %ecx                ## encoding: [0xb9,0x04,0x00,0x00,0x00]
movq %rdi, %rax              ## encoding: [0x48,0x89,0xf8]
mulq %rcx                    ## encoding: [0x48,0xf7,0xe1]
testq %rdx, %rdx              ## encoding: [0x48,0x85,0xd2]
movq $-1, %rdi               ## encoding: [0x48,0xc7,0xc7,0xff,0xff,0xff,0xff]
cmoveq %rax, %rdi              ## encoding: [0x48,0x0f,0x44,0xf8]
jmp __Znam                  ## TAILCALL
                                        ## encoding: [0xeb,A]

to:

__Z4funcl:                              ## @_Z4funcl
movl $4, %ecx                ## encoding: [0xb9,0x04,0x00,0x00,0x00]
movq %rdi, %rax              ## encoding: [0x48,0x89,0xf8]
mulq %rcx                    ## encoding: [0x48,0xf7,0xe1]
cmpq $1, %rdx                ## encoding: [0x48,0x83,0xfa,0x01]
sbbq %rdi, %rdi              ## encoding: [0x48,0x19,0xff]
notq %rdi                    ## encoding: [0x48,0xf7,0xd7]
orq %rax, %rdi              ## encoding: [0x48,0x09,0xc7]
jmp __Znam                  ## TAILCALL
                                        ## encoding: [0xeb,A]

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

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/select.ll

index 3e7b0bbd6ae06cf14978b5c0f7f919d0a17661ad..1df53b994720c8c0104560ee8663e8dd4a8165b0 100644 (file)
@@ -7213,6 +7213,11 @@ static bool isZero(SDValue V) {
   return C && C->isNullValue();
 }
 
+static bool isAllOnes(SDValue V) {
+  ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
+  return C && C->isAllOnesValue();
+}
+
 SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
   bool addTest = true;
   SDValue Cond  = Op.getOperand(0);
@@ -7228,26 +7233,31 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
   }
 
   // (select (x == 0), -1, y) -> (sign_bit (x - 1)) | y
+  // (select (x == 0), y, -1) -> ~(sign_bit (x - 1)) | y
   // (select (x != 0), y, -1) -> (sign_bit (x - 1)) | y
+  // (select (x != 0), -1, y) -> ~(sign_bit (x - 1)) | y
   if (Cond.getOpcode() == X86ISD::SETCC &&
-      Cond.getOperand(1).getOpcode() == X86ISD::CMP) {
+      Cond.getOperand(1).getOpcode() == X86ISD::CMP &&
+      isZero(Cond.getOperand(1).getOperand(1))) {
     SDValue Cmp = Cond.getOperand(1);
     
     unsigned CondCode =cast<ConstantSDNode>(Cond.getOperand(0))->getZExtValue();
     
-    ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Op1);
-    ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(Op2);
-    if ((N1C && N1C->isAllOnesValue() && CondCode == X86::COND_E) ||
-        (N2C && N2C->isAllOnesValue() && CondCode == X86::COND_NE)) {
-      SDValue Y = CondCode == X86::COND_NE ? Op1 : Op2;
+    if ((isAllOnes(Op1) || isAllOnes(Op2)) && 
+        (CondCode == X86::COND_E || CondCode == X86::COND_NE)) {
+      SDValue Y = isAllOnes(Op2) ? Op1 : Op2;
 
       SDValue CmpOp0 = Cmp.getOperand(0);
       Cmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32,
                         CmpOp0, DAG.getConstant(1, CmpOp0.getValueType()));
       
-      SDValue Res = 
+      SDValue Res =   // Res = 0 or -1.
         DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(),
                     DAG.getConstant(X86::COND_B, MVT::i8), Cmp);
+      
+      if (isAllOnes(Op1) != (CondCode == X86::COND_E))
+        Res = DAG.getNOT(DL, Res, Res.getValueType());
+      
       ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(Op2);
       if (N2C == 0 || !N2C->isNullValue())
         Res = DAG.getNode(ISD::OR, DL, Res.getValueType(), Res, Y);
index 8b8fb3b19ce0eff170c8196b1511d04cca7d4c58..11ace19a13616838e50def86ecfe6a5ca1ae03b0 100644 (file)
@@ -153,5 +153,29 @@ define i64 @test10(i64 %x, i64 %y) nounwind readnone ssp noredzone {
 
 
 
+define i64 @test11(i64 %x, i64 %y) nounwind readnone ssp noredzone {
+  %cmp = icmp eq i64 %x, 0
+  %cond = select i1 %cmp, i64 %y, i64 -1
+  ret i64 %cond
+; CHECK: test11:
+; CHECK: cmpq  $1, %rdi
+; CHECK: sbbq  %rax, %rax
+; CHECK: notq %rax
+; CHECK: orq   %rsi, %rax
+; CHECK: ret
+}
+
+define i64 @test11a(i64 %x, i64 %y) nounwind readnone ssp noredzone {
+  %cmp = icmp ne i64 %x, 0
+  %cond = select i1 %cmp, i64 -1, i64 %y
+  ret i64 %cond
+; CHECK: test11a:
+; CHECK: cmpq  $1, %rdi
+; CHECK: sbbq  %rax, %rax
+; CHECK: notq %rax
+; CHECK: orq   %rsi, %rax
+; CHECK: ret
+}
+