[llvm] r276221 - [InstCombine] LogicOpc (zext X), C --> zext (LogicOpc X, C) (PR28476)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 17:24:18 PDT 2016


Author: spatel
Date: Wed Jul 20 19:24:18 2016
New Revision: 276221

URL: http://llvm.org/viewvc/llvm-project?rev=276221&view=rev
Log:
[InstCombine] LogicOpc (zext X), C --> zext (LogicOpc X, C) (PR28476)

The benefits of this change include:
1. Remove DeMorgan-matching code that was added specifically to work-around 
   the missing transform in http://reviews.llvm.org/rL248634.
2. Makes the DeMorgan transform work for vectors too.
3. Fix PR28476: https://llvm.org/bugs/show_bug.cgi?id=28476

Extending this transform to other casts and other associative operators may
be useful too. See https://reviews.llvm.org/D22421 for a prerequisite for
doing that though.

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


Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/apint-select.ll
    llvm/trunk/test/Transforms/InstCombine/assoc-cast-assoc.ll
    llvm/trunk/test/Transforms/InstCombine/cast.ll
    llvm/trunk/test/Transforms/InstCombine/demorgan-zext.ll
    llvm/trunk/test/Transforms/InstCombine/select.ll
    llvm/trunk/test/Transforms/InstCombine/zeroext-and-reduce.ll
    llvm/trunk/test/Transforms/InstCombine/zext.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Wed Jul 20 19:24:18 2016
@@ -1123,26 +1123,6 @@ static Instruction *matchDeMorgansLaws(B
         return BinaryOperator::CreateNot(LogicOp);
       }
 
-  // De Morgan's Law in disguise:
-  // (zext(bool A) ^ 1) & (zext(bool B) ^ 1) -> zext(~(A | B))
-  // (zext(bool A) ^ 1) | (zext(bool B) ^ 1) -> zext(~(A & B))
-  Value *A = nullptr;
-  Value *B = nullptr;
-  ConstantInt *C1 = nullptr;
-  if (match(Op0, m_OneUse(m_Xor(m_ZExt(m_Value(A)), m_ConstantInt(C1)))) &&
-      match(Op1, m_OneUse(m_Xor(m_ZExt(m_Value(B)), m_Specific(C1))))) {
-    // TODO: This check could be loosened to handle different type sizes.
-    // Alternatively, we could fix the definition of m_Not to recognize a not
-    // operation hidden by a zext?
-    if (A->getType()->isIntegerTy(1) && B->getType()->isIntegerTy(1) &&
-        C1->isOne()) {
-      Value *LogicOp = Builder->CreateBinOp(Opcode, A, B,
-                                            I.getName() + ".demorgan");
-      Value *Not = Builder->CreateNot(LogicOp);
-      return CastInst::CreateZExtOrBitCast(Not, I.getType());
-    }
-  }
-
   return nullptr;
 }
 
@@ -1199,6 +1179,22 @@ Instruction *InstCombiner::foldCastedBit
     return CastInst::CreateBitOrPointerCast(NewOp, DestTy);
   }
 
+  // Similarly, if one operand is zexted and the other is a constant, move the
+  // logic operation ahead of the zext if the constant is unchanged in the
+  // smaller source type. Performing the logic in a smaller type may provide
+  // more information to later folds, and the smaller logic instruction may be
+  // cheaper (particularly in the case of vectors).
+  Value *X;
+  if (match(Op0, m_OneUse(m_ZExt(m_Value(X)))) && match(Op1, m_Constant(C))) {
+    Constant *TruncC = ConstantExpr::getTrunc(C, SrcTy);
+    Constant *ZextTruncC = ConstantExpr::getZExt(TruncC, DestTy);
+    if (ZextTruncC == C) {
+      // LogicOpc (zext X), C --> zext (LogicOpc X, C)
+      Value *NewOp = Builder->CreateBinOp(LogicOpc, X, TruncC);
+      return new ZExtInst(NewOp, DestTy);
+    }
+  }
+
   CastInst *Cast1 = dyn_cast<CastInst>(Op1);
   if (!Cast1)
     return nullptr;

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Wed Jul 20 19:24:18 2016
@@ -920,14 +920,6 @@ Instruction *InstCombiner::visitZExt(ZEx
     return BinaryOperator::CreateXor(Builder->CreateAnd(X, ZC), ZC);
   }
 
-  // zext (xor i1 X, true) to i32  --> xor (zext i1 X to i32), 1
-  if (SrcI && SrcI->hasOneUse() &&
-      SrcI->getType()->getScalarType()->isIntegerTy(1) &&
-      match(SrcI, m_Not(m_Value(X))) && (!X->hasOneUse() || !isa<CmpInst>(X))) {
-    Value *New = Builder->CreateZExt(X, CI.getType());
-    return BinaryOperator::CreateXor(New, ConstantInt::get(CI.getType(), 1));
-  }
-
   return nullptr;
 }
 

Modified: llvm/trunk/test/Transforms/InstCombine/apint-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-select.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/apint-select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/apint-select.ll Wed Jul 20 19:24:18 2016
@@ -23,8 +23,8 @@ define i41 @sext(i1 %C) {
 
 define i999 @not_zext(i1 %C) {
 ; CHECK-LABEL: @not_zext(
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 %C to i999
-; CHECK-NEXT:    [[V:%.*]] = xor i999 [[TMP1]], 1
+; CHECK-NEXT:    [[NOT_C:%.*]] = xor i1 %C, true
+; CHECK-NEXT:    [[V:%.*]] = zext i1 [[NOT_C]] to i999
 ; CHECK-NEXT:    ret i999 [[V]]
 ;
   %V = select i1 %C, i999 0, i999 1
@@ -63,8 +63,8 @@ define <2 x i32> @sext_vec(<2 x i1> %C)
 
 define <2 x i999> @not_zext_vec(<2 x i1> %C) {
 ; CHECK-LABEL: @not_zext_vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i1> %C to <2 x i999>
-; CHECK-NEXT:    [[V:%.*]] = xor <2 x i999> [[TMP1]], <i999 1, i999 1>
+; CHECK-NEXT:    [[NOT_C:%.*]] = xor <2 x i1> %C, <i1 true, i1 true>
+; CHECK-NEXT:    [[V:%.*]] = zext <2 x i1> [[NOT_C]] to <2 x i999>
 ; CHECK-NEXT:    ret <2 x i999> [[V]]
 ;
   %V = select <2 x i1> %C, <2 x i999> <i999 0, i999 0>, <2 x i999> <i999 1, i999 1>

Modified: llvm/trunk/test/Transforms/InstCombine/assoc-cast-assoc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/assoc-cast-assoc.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/assoc-cast-assoc.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/assoc-cast-assoc.ll Wed Jul 20 19:24:18 2016
@@ -53,8 +53,8 @@ define <2 x i32> @OrZextOrVec(<2 x i2> %
 
 define i5 @AndZextAnd(i3 %a) {
 ; CHECK-LABEL: @AndZextAnd(
-; CHECK-NEXT:    [[CAST:%.*]] = zext i3 %a to i5
-; CHECK-NEXT:    [[OP2:%.*]] = and i5 [[CAST]], 2
+; CHECK-NEXT:    [[TMP1:%.*]] = and i3 %a, 2
+; CHECK-NEXT:    [[OP2:%.*]] = zext i3 [[TMP1]] to i5
 ; CHECK-NEXT:    ret i5 [[OP2]]
 ;
   %op1 = and i3 %a, 3
@@ -65,8 +65,8 @@ define i5 @AndZextAnd(i3 %a) {
 
 define <2 x i32> @AndZextAndVec(<2 x i8> %a) {
 ; CHECK-LABEL: @AndZextAndVec(
-; CHECK-NEXT:    [[CAST:%.*]] = zext <2 x i8> %a to <2 x i32>
-; CHECK-NEXT:    [[OP2:%.*]] = and <2 x i32> [[CAST]], <i32 5, i32 0>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> %a, <i8 5, i8 0>
+; CHECK-NEXT:    [[OP2:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32>
 ; CHECK-NEXT:    ret <2 x i32> [[OP2]]
 ;
   %op1 = and <2 x i8> %a, <i8 7, i8 0>

Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Wed Jul 20 19:24:18 2016
@@ -637,9 +637,9 @@ define i32 @test52(i64 %A) {
 
 define i64 @test53(i32 %A) {
 ; CHECK-LABEL: @test53(
-; CHECK-NEXT:    [[B:%.*]] = zext i32 %A to i64
-; CHECK-NEXT:    [[C:%.*]] = and i64 [[B]], 7224
-; CHECK-NEXT:    [[D:%.*]] = or i64 [[C]], 32962
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %A, 7224
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], 32962
+; CHECK-NEXT:    [[D:%.*]] = zext i32 [[TMP2]] to i64
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %B = trunc i32 %A to i16
@@ -665,8 +665,8 @@ define i32 @test54(i64 %A) {
 
 define i64 @test55(i32 %A) {
 ; CHECK-LABEL: @test55(
-; CHECK-NEXT:    [[B:%.*]] = zext i32 %A to i64
-; CHECK-NEXT:    [[C:%.*]] = and i64 [[B]], 7224
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %A, 7224
+; CHECK-NEXT:    [[C:%.*]] = zext i32 [[TMP1]] to i64
 ; CHECK-NEXT:    [[D:%.*]] = or i64 [[C]], -32574
 ; CHECK-NEXT:    ret i64 [[D]]
 ;

Modified: llvm/trunk/test/Transforms/InstCombine/demorgan-zext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/demorgan-zext.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/demorgan-zext.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/demorgan-zext.ll Wed Jul 20 19:24:18 2016
@@ -5,9 +5,9 @@
 
 define i32 @demorgan_or(i1 %X, i1 %Y) {
 ; CHECK-LABEL: @demorgan_or(
-; CHECK-NEXT:    [[OR_DEMORGAN:%.*]] = and i1 %X, %Y
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[OR_DEMORGAN]] to i32
-; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[TMP1]], 1
+; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and i1 %X, %Y
+; CHECK-NEXT:    [[OR1:%.*]] = xor i1 [[OR1_DEMORGAN]], true
+; CHECK-NEXT:    [[OR:%.*]] = zext i1 [[OR:%.*]]1 to i32
 ; CHECK-NEXT:    ret i32 [[OR]]
 ;
   %zextX = zext i1 %X to i32
@@ -20,9 +20,9 @@ define i32 @demorgan_or(i1 %X, i1 %Y) {
 
 define i32 @demorgan_and(i1 %X, i1 %Y) {
 ; CHECK-LABEL: @demorgan_and(
-; CHECK-NEXT:    [[AND_DEMORGAN:%.*]] = or i1 %X, %Y
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[AND_DEMORGAN]] to i32
-; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], 1
+; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or i1 %X, %Y
+; CHECK-NEXT:    [[AND1:%.*]] = xor i1 [[AND1_DEMORGAN]], true
+; CHECK-NEXT:    [[AND:%.*]] = zext i1 [[AND:%.*]]1 to i32
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %zextX = zext i1 %X to i32
@@ -33,15 +33,11 @@ define i32 @demorgan_and(i1 %X, i1 %Y) {
   ret i32 %and
 }
 
-; FIXME: Vectors should get the same transform.
-
 define <2 x i32> @demorgan_or_vec(<2 x i1> %X, <2 x i1> %Y) {
 ; CHECK-LABEL: @demorgan_or_vec(
-; CHECK-NEXT:    [[ZEXTX:%.*]] = zext <2 x i1> %X to <2 x i32>
-; CHECK-NEXT:    [[ZEXTY:%.*]] = zext <2 x i1> %Y to <2 x i32>
-; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[ZEXTX]], <i32 1, i32 1>
-; CHECK-NEXT:    [[NOTY:%.*]] = xor <2 x i32> [[ZEXTY]], <i32 1, i32 1>
-; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[NOTX]], [[NOTY]]
+; CHECK-NEXT:    [[OR1_DEMORGAN:%.*]] = and <2 x i1> %X, %Y
+; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i1> [[OR1_DEMORGAN]], <i1 true, i1 true>
+; CHECK-NEXT:    [[OR:%.*]] = zext <2 x i1> [[OR:%.*]]1 to <2 x i32>
 ; CHECK-NEXT:    ret <2 x i32> [[OR]]
 ;
   %zextX = zext <2 x i1> %X to <2 x i32>
@@ -54,11 +50,9 @@ define <2 x i32> @demorgan_or_vec(<2 x i
 
 define <2 x i32> @demorgan_and_vec(<2 x i1> %X, <2 x i1> %Y) {
 ; CHECK-LABEL: @demorgan_and_vec(
-; CHECK-NEXT:    [[ZEXTX:%.*]] = zext <2 x i1> %X to <2 x i32>
-; CHECK-NEXT:    [[ZEXTY:%.*]] = zext <2 x i1> %Y to <2 x i32>
-; CHECK-NEXT:    [[NOTX:%.*]] = xor <2 x i32> [[ZEXTX]], <i32 1, i32 1>
-; CHECK-NEXT:    [[NOTY:%.*]] = xor <2 x i32> [[ZEXTY]], <i32 1, i32 1>
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[NOTX]], [[NOTY]]
+; CHECK-NEXT:    [[AND1_DEMORGAN:%.*]] = or <2 x i1> %X, %Y
+; CHECK-NEXT:    [[AND1:%.*]] = xor <2 x i1> [[AND1_DEMORGAN]], <i1 true, i1 true>
+; CHECK-NEXT:    [[AND:%.*]] = zext <2 x i1> [[AND:%.*]]1 to <2 x i32>
 ; CHECK-NEXT:    ret <2 x i32> [[AND]]
 ;
   %zextX = zext <2 x i1> %X to <2 x i32>
@@ -69,15 +63,12 @@ define <2 x i32> @demorgan_and_vec(<2 x
   ret <2 x i32> %and
 }
 
-; FIXME: If the xor was canonicalized to a 'not', then this would simplify.
-
 define i32 @PR28476(i32 %x, i32 %y) {
 ; CHECK-LABEL: @PR28476(
-; CHECK-NEXT:    [[CMP0:%.*]] = icmp ne i32 %x, 0
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 %y, 0
-; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[AND]] to i32
-; CHECK-NEXT:    [[COND:%.*]] = xor i32 [[ZEXT]], 1
+; CHECK-NEXT:    [[NOTLHS:%.*]] = icmp eq i32 %x, 0
+; CHECK-NEXT:    [[NOTRHS:%.*]] = icmp eq i32 %y, 0
+; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[NOTRHS]], [[NOTLHS]]
+; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[TMP1]] to i32
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %cmp0 = icmp ne i32 %x, 0

Modified: llvm/trunk/test/Transforms/InstCombine/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select.ll Wed Jul 20 19:24:18 2016
@@ -242,8 +242,8 @@ define i32 @test12a(i1 %cond, i32 %a) {
 
 define i32 @test12b(i1 %cond, i32 %a) {
 ; CHECK-LABEL: @test12b(
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i1 %cond to i32
-; CHECK-NEXT:    [[B:%.*]] = xor i32 [[TMP1]], 1
+; CHECK-NEXT:    [[NOT_COND:%.*]] = xor i1 %cond, true
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[NOT_COND]] to i32
 ; CHECK-NEXT:    [[D:%.*]] = ashr i32 %a, [[B]]
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
@@ -1193,8 +1193,8 @@ define i64 @select_icmp_x_and_8_ne_0_y_x
 define i64 @select_icmp_x_and_8_ne_0_y_or_8(i32 %x, i64 %y) {
 ; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_or_8(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 %x, 8
-; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[AND]] to i64
-; CHECK-NEXT:    [[TMP2:%.*]] = xor i64 [[TMP1]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[AND]], 8
+; CHECK-NEXT:    [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
 ; CHECK-NEXT:    [[TMP3:%.*]] = or i64 [[TMP2]], %y
 ; CHECK-NEXT:    ret i64 [[TMP3]]
 ;

Modified: llvm/trunk/test/Transforms/InstCombine/zeroext-and-reduce.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/zeroext-and-reduce.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/zeroext-and-reduce.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/zeroext-and-reduce.ll Wed Jul 20 19:24:18 2016
@@ -3,8 +3,8 @@
 
 define i32 @test1(i8 %X) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    [[Y:%.*]] = zext i8 %X to i32
-; CHECK-NEXT:    [[Z:%.*]] = and i32 [[Y]], 8
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 %X, 8
+; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[TMP1]] to i32
 ; CHECK-NEXT:    ret i32 [[Z]]
 ;
   %Y = zext i8 %X to i32

Modified: llvm/trunk/test/Transforms/InstCombine/zext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/zext.ll?rev=276221&r1=276220&r2=276221&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/zext.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/zext.ll Wed Jul 20 19:24:18 2016
@@ -13,8 +13,8 @@ define i64 @test_sext_zext(i16 %A) {
 
 define <2 x i64> @test2(<2 x i1> %A) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i1> %A to <2 x i64>
-; CHECK-NEXT:    [[ZEXT:%.*]] = xor <2 x i64> [[TMP1]], <i64 1, i64 1>
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i1> %A, <i1 true, i1 true>
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i1> [[XOR]] to <2 x i64>
 ; CHECK-NEXT:    ret <2 x i64> [[ZEXT]]
 ;
   %xor = xor <2 x i1> %A, <i1 true, i1 true>
@@ -46,13 +46,10 @@ define <2 x i64> @test4(<2 x i64> %A) {
   ret <2 x i64> %zext
 }
 
-; FIXME: If the xor was done in the smaller type, the back-to-back zexts would get combined.
-
 define i64 @fold_xor_zext_sandwich(i1 %a) {
 ; CHECK-LABEL: @fold_xor_zext_sandwich(
-; CHECK-NEXT:    [[ZEXT1:%.*]] = zext i1 %a to i32
-; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[ZEXT1]], 1
-; CHECK-NEXT:    [[ZEXT2:%.*]] = zext i32 [[XOR]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 %a, true
+; CHECK-NEXT:    [[ZEXT2:%.*]] = zext i1 [[TMP1]] to i64
 ; CHECK-NEXT:    ret i64 [[ZEXT2]]
 ;
   %zext1 = zext i1 %a to i32
@@ -63,9 +60,9 @@ define i64 @fold_xor_zext_sandwich(i1 %a
 
 define <2 x i64> @fold_xor_zext_sandwich_vec(<2 x i1> %a) {
 ; CHECK-LABEL: @fold_xor_zext_sandwich_vec(
-; CHECK-NEXT:    [[ZEXT1:%.*]] = zext <2 x i1> %a to <2 x i64>
-; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i64> [[ZEXT1]], <i64 1, i64 1>
-; CHECK-NEXT:    ret <2 x i64> [[XOR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> %a, <i1 true, i1 true>
+; CHECK-NEXT:    [[ZEXT2:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
+; CHECK-NEXT:    ret <2 x i64> [[ZEXT2]]
 ;
   %zext1 = zext <2 x i1> %a to <2 x i32>
   %xor = xor <2 x i32> %zext1, <i32 1, i32 1>




More information about the llvm-commits mailing list