Tweak my last commit to be less conservative about uses.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 8 Jan 2012 21:12:51 +0000 (21:12 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 8 Jan 2012 21:12:51 +0000 (21:12 +0000)
We still save an instruction when just the "and" part is replaced.
Also change the code to match comments more closely.

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

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/sign-test-and-or.ll

index 96ca40a3cf95db5dbf263ae96f70250251304783..b4d3e625ae04b6178345b264faa8ee7abb527a61 100644 (file)
@@ -745,18 +745,17 @@ Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
   }
 
   // (X & C) == 0 & X > -1  ->  (X & (C | SignBit)) == 0
-  if (LHS->hasOneUse() && RHS->hasOneUse() &&
-      ((LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero() &&
-        RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
-       (RHSCC == ICmpInst::ICMP_EQ && RHSCst->isZero() &&
-        LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()))) {
-    BinaryOperator *BO =
-      dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_EQ ? Val : Val2);
-    ConstantInt *AndCst;
-    if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
-      APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
-      BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
-      return BO == Val ? LHS : RHS;
+  if ((LHSCC == ICmpInst::ICMP_EQ  && LHSCst->isZero() &&
+       RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
+      (RHSCC == ICmpInst::ICMP_EQ  && RHSCst->isZero() &&
+       LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue())) {
+    ICmpInst *I = LHSCC == ICmpInst::ICMP_EQ ? LHS : RHS;
+    Value *X; ConstantInt *C;
+    if (I->hasOneUse() &&
+        match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+      APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+      return Builder->CreateICmpEQ(Builder->CreateAnd(X, Builder->getInt(New)),
+                                   I->getOperand(1));
     }
   }
   
@@ -1458,19 +1457,18 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
     }
   }
 
-  // (X & C) != 0 & X < 0  ->  (X & (C | SignBit)) != 0
-  if (LHS->hasOneUse() && RHS->hasOneUse() &&
-      ((LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero() &&
-        RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
-       (RHSCC == ICmpInst::ICMP_NE && RHSCst->isZero() &&
-        LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()))) {
-    BinaryOperator *BO =
-      dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_NE ? Val : Val2);
-    ConstantInt *AndCst;
-    if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
-      APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
-      BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
-      return BO == Val ? LHS : RHS;
+  // (X & C) != 0 | X < 0  ->  (X & (C | SignBit)) != 0
+  if ((LHSCC == ICmpInst::ICMP_NE  && LHSCst->isZero() &&
+       RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
+      (RHSCC == ICmpInst::ICMP_NE  && RHSCst->isZero() &&
+       LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero())) {
+    ICmpInst *I = LHSCC == ICmpInst::ICMP_NE ? LHS : RHS;
+    Value *X; ConstantInt *C;
+    if (I->hasOneUse() &&
+        match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+      APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+      return Builder->CreateICmpNE(Builder->CreateAnd(X, Builder->getInt(New)),
+                                   I->getOperand(1));
     }
   }
 
index 2a5f7725066ce93ea5252eea2af2a2f8d19a121c..3f2141d7a9f2c1a89f07936c8a7f1010e72a0333 100644 (file)
@@ -86,9 +86,9 @@ define void @test5(i32 %a) nounwind {
   br i1 %or.cond, label %if.then, label %if.end
 
 ; CHECK: @test5
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
 
 if.then:
   tail call void @foo() nounwind
@@ -106,9 +106,9 @@ define void @test6(i32 %a) nounwind {
   br i1 %or.cond, label %if.then, label %if.end
 
 ; CHECK: @test6
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
 
 if.then:
   tail call void @foo() nounwind
@@ -126,9 +126,9 @@ define void @test7(i32 %a) nounwind {
   br i1 %or.cond, label %if.then, label %if.end
 
 ; CHECK: @test7
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
 
 if.then:
   tail call void @foo() nounwind
@@ -146,9 +146,9 @@ define void @test8(i32 %a) nounwind {
   br i1 %or.cond, label %if.then, label %if.end
 
 ; CHECK: @test8
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
 
 if.then:
   tail call void @foo() nounwind