]> granicus.if.org Git - llvm/commitdiff
[InstCombine] Remove the (not (sext)) case from foldBoolSextMaskToSelect and inline...
authorCraig Topper <craig.topper@intel.com>
Fri, 4 Aug 2017 16:07:20 +0000 (16:07 +0000)
committerCraig Topper <craig.topper@intel.com>
Fri, 4 Aug 2017 16:07:20 +0000 (16:07 +0000)
Summary:
The (not (sext)) case is really (xor (sext), -1) which should have been simplified to (sext (xor, 1)) before we got here. So we shouldn't need to handle it.

With that taken care of we only need to two cases so don't need the swap anymore. This makes us in sync with the equivalent code in visitOr so inline this to match.

Reviewers: spatel, eli.friedman, majnemer

Reviewed By: spatel

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D36240

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

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/vector-casts.ll

index 62a73cca4b7a706e4bd6f8f91a3fa652ff27d3b5..a3749a1581bd168fc7455b4a385d35ada972f34b 100644 (file)
@@ -1188,31 +1188,6 @@ Instruction *InstCombiner::foldCastedBitwiseLogic(BinaryOperator &I) {
   return nullptr;
 }
 
-static Instruction *foldBoolSextMaskToSelect(BinaryOperator &I) {
-  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-
-  // Canonicalize SExt or Not to the LHS
-  if (match(Op1, m_SExt(m_Value())) || match(Op1, m_Not(m_Value()))) {
-    std::swap(Op0, Op1);
-  }
-
-  // Fold (and (sext bool to A), B) --> (select bool, B, 0)
-  Value *X = nullptr;
-  if (match(Op0, m_SExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1)) {
-    Value *Zero = Constant::getNullValue(Op1->getType());
-    return SelectInst::Create(X, Op1, Zero);
-  }
-
-  // Fold (and ~(sext bool to A), B) --> (select bool, 0, B)
-  if (match(Op0, m_Not(m_SExt(m_Value(X)))) &&
-      X->getType()->isIntOrIntVectorTy(1)) {
-    Value *Zero = Constant::getNullValue(Op0->getType());
-    return SelectInst::Create(X, Zero, Op1);
-  }
-
-  return nullptr;
-}
-
 static Instruction *foldAndToXor(BinaryOperator &I,
                                  InstCombiner::BuilderTy &Builder) {
   assert(I.getOpcode() == Instruction::And);
@@ -1480,8 +1455,14 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
   if (Instruction *CastedAnd = foldCastedBitwiseLogic(I))
     return CastedAnd;
 
-  if (Instruction *Select = foldBoolSextMaskToSelect(I))
-    return Select;
+  // and(sext(A), B) / and(B, sext(A)) --> A ? B : 0, where A is i1 or <N x i1>.
+  Value *A;
+  if (match(Op0, m_OneUse(m_SExt(m_Value(A)))) &&
+      A->getType()->isIntOrIntVectorTy(1))
+    return SelectInst::Create(A, Op1, Constant::getNullValue(I.getType()));
+  if (match(Op1, m_OneUse(m_SExt(m_Value(A)))) &&
+      A->getType()->isIntOrIntVectorTy(1))
+    return SelectInst::Create(A, Op0, Constant::getNullValue(I.getType()));
 
   return Changed ? &I : nullptr;
 }
index e52e063a405aeb404887d8215051a468ffedb4a8..447f86f05d26148a0e9d3514a6ad46f3910eb2eb 100644 (file)
@@ -61,7 +61,7 @@ define <2 x i64> @test5(<4 x float> %a, <4 x float> %b) {
 ; CHECK-LABEL: @test5(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <4 x float> %a, zeroinitializer
 ; CHECK-NEXT:    [[CMP4:%.*]] = fcmp ult <4 x float> %b, zeroinitializer
-; CHECK-NEXT:    [[NARROW:%.*]] = and <4 x i1> [[CMP4]], [[CMP]]
+; CHECK-NEXT:    [[NARROW:%.*]] = and <4 x i1> [[CMP]], [[CMP4]]
 ; CHECK-NEXT:    [[AND:%.*]] = sext <4 x i1> [[NARROW]] to <4 x i32>
 ; CHECK-NEXT:    [[CONV:%.*]] = bitcast <4 x i32> [[AND]] to <2 x i64>
 ; CHECK-NEXT:    ret <2 x i64> [[CONV]]