[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