Skip to content

Commit 31b38e8

Browse files
committed
[PatternMatch] Do not accept undef elements in m_AllOnes() and friends
Change all the cstval_pred_ty based PatternMatch helpers (things like m_AllOnes and m_Zero) to only allow poison elements inside vector splats, not undef elements. Historically, we used to represent non-demanded elements in vectors using undef. Nowadays, we use poison instead. As such, I believe that support for undef in vector splats is no longer useful. At the same time, while poison splat elements are pretty much always safe to ignore, this is not generally the case for undef elements. We have existing miscompiles in our tests due to this (see the masked-merge-*.ll tests changed here) and it's easy to miss such cases in the future, now that we write tests using poison instead of undef elements. I think overall, keeping support for undef elements no longer makes sense, and we should drop it. Once this is done consistently, I think we may also consider allowing poison in m_APInt by default, as doing that change is much less risky than doing the same with undef. This PR is a stub for discussion -- this change has more than a hundred test failures in InstCombine alone, and I don't want to update all of them before we reach a consensus. The abs-1.ll test is a representative example of how I would update most tests: By replacing undef with poison. I don't think there is value in retaining the undef test coverage anymore at this point.
1 parent e8a3b72 commit 31b38e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+649
-445
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ template <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
345345

346346
/// This helper class is used to match constant scalars, vector splats,
347347
/// and fixed width vectors that satisfy a specified predicate.
348-
/// For fixed width vector constants, undefined elements are ignored.
348+
/// For fixed width vector constants, poison elements are ignored.
349349
template <typename Predicate, typename ConstantVal>
350350
struct cstval_pred_ty : public Predicate {
351351
template <typename ITy> bool match(ITy *V) {
@@ -364,19 +364,19 @@ struct cstval_pred_ty : public Predicate {
364364
// Non-splat vector constant: check each element for a match.
365365
unsigned NumElts = FVTy->getNumElements();
366366
assert(NumElts != 0 && "Constant vector with no elements?");
367-
bool HasNonUndefElements = false;
367+
bool HasNonPoisonElements = false;
368368
for (unsigned i = 0; i != NumElts; ++i) {
369369
Constant *Elt = C->getAggregateElement(i);
370370
if (!Elt)
371371
return false;
372-
if (isa<UndefValue>(Elt))
372+
if (isa<PoisonValue>(Elt))
373373
continue;
374374
auto *CV = dyn_cast<ConstantVal>(Elt);
375375
if (!CV || !this->isValue(CV->getValue()))
376376
return false;
377-
HasNonUndefElements = true;
377+
HasNonPoisonElements = true;
378378
}
379-
return HasNonUndefElements;
379+
return HasNonPoisonElements;
380380
}
381381
}
382382
return false;
@@ -2587,31 +2587,6 @@ m_Not(const ValTy &V) {
25872587
return m_c_Xor(m_AllOnes(), V);
25882588
}
25892589

2590-
template <typename ValTy> struct NotForbidUndef_match {
2591-
ValTy Val;
2592-
NotForbidUndef_match(const ValTy &V) : Val(V) {}
2593-
2594-
template <typename OpTy> bool match(OpTy *V) {
2595-
// We do not use m_c_Xor because that could match an arbitrary APInt that is
2596-
// not -1 as C and then fail to match the other operand if it is -1.
2597-
// This code should still work even when both operands are constants.
2598-
Value *X;
2599-
const APInt *C;
2600-
if (m_Xor(m_Value(X), m_APIntForbidUndef(C)).match(V) && C->isAllOnes())
2601-
return Val.match(X);
2602-
if (m_Xor(m_APIntForbidUndef(C), m_Value(X)).match(V) && C->isAllOnes())
2603-
return Val.match(X);
2604-
return false;
2605-
}
2606-
};
2607-
2608-
/// Matches a bitwise 'not' as 'xor V, -1' or 'xor -1, V'. For vectors, the
2609-
/// constant value must be composed of only -1 scalar elements.
2610-
template <typename ValTy>
2611-
inline NotForbidUndef_match<ValTy> m_NotForbidUndef(const ValTy &V) {
2612-
return NotForbidUndef_match<ValTy>(V);
2613-
}
2614-
26152590
/// Matches an SMin with LHS and RHS in either order.
26162591
template <typename LHS, typename RHS>
26172592
inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ static Value *simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact,
15121512

15131513
// -1 >>a X --> -1
15141514
// (-1 << X) a>> X --> -1
1515-
// Do not return Op0 because it may contain undef elements if it's a vector.
1515+
// We could return the original -1 constant to preserve poison elements.
15161516
if (match(Op0, m_AllOnes()) ||
15171517
match(Op0, m_Shl(m_AllOnes(), m_Specific(Op1))))
15181518
return Constant::getAllOnesValue(Op0->getType());
@@ -2282,7 +2282,7 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
22822282
// (B ^ ~A) | (A & B) --> B ^ ~A
22832283
// (~A ^ B) | (B & A) --> ~A ^ B
22842284
// (B ^ ~A) | (B & A) --> B ^ ~A
2285-
if (match(X, m_c_Xor(m_NotForbidUndef(m_Value(A)), m_Value(B))) &&
2285+
if (match(X, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
22862286
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
22872287
return X;
22882288

@@ -2299,31 +2299,29 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
22992299
// (B & ~A) | ~(A | B) --> ~A
23002300
// (B & ~A) | ~(B | A) --> ~A
23012301
Value *NotA;
2302-
if (match(X,
2303-
m_c_And(m_CombineAnd(m_Value(NotA), m_NotForbidUndef(m_Value(A))),
2304-
m_Value(B))) &&
2302+
if (match(X, m_c_And(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
2303+
m_Value(B))) &&
23052304
match(Y, m_Not(m_c_Or(m_Specific(A), m_Specific(B)))))
23062305
return NotA;
23072306
// The same is true of Logical And
23082307
// TODO: This could share the logic of the version above if there was a
23092308
// version of LogicalAnd that allowed more than just i1 types.
2310-
if (match(X, m_c_LogicalAnd(
2311-
m_CombineAnd(m_Value(NotA), m_NotForbidUndef(m_Value(A))),
2312-
m_Value(B))) &&
2309+
if (match(X, m_c_LogicalAnd(m_CombineAnd(m_Value(NotA), m_Not(m_Value(A))),
2310+
m_Value(B))) &&
23132311
match(Y, m_Not(m_c_LogicalOr(m_Specific(A), m_Specific(B)))))
23142312
return NotA;
23152313

23162314
// ~(A ^ B) | (A & B) --> ~(A ^ B)
23172315
// ~(A ^ B) | (B & A) --> ~(A ^ B)
23182316
Value *NotAB;
2319-
if (match(X, m_CombineAnd(m_NotForbidUndef(m_Xor(m_Value(A), m_Value(B))),
2317+
if (match(X, m_CombineAnd(m_Not(m_Xor(m_Value(A), m_Value(B))),
23202318
m_Value(NotAB))) &&
23212319
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
23222320
return NotAB;
23232321

23242322
// ~(A & B) | (A ^ B) --> ~(A & B)
23252323
// ~(A & B) | (B ^ A) --> ~(A & B)
2326-
if (match(X, m_CombineAnd(m_NotForbidUndef(m_And(m_Value(A), m_Value(B))),
2324+
if (match(X, m_CombineAnd(m_Not(m_And(m_Value(A), m_Value(B))),
23272325
m_Value(NotAB))) &&
23282326
match(Y, m_c_Xor(m_Specific(A), m_Specific(B))))
23292327
return NotAB;
@@ -2553,9 +2551,8 @@ static Value *simplifyXorInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
25532551
// The 'not' op must contain a complete -1 operand (no undef elements for
25542552
// vector) for the transform to be safe.
25552553
Value *NotA;
2556-
if (match(X,
2557-
m_c_Or(m_CombineAnd(m_NotForbidUndef(m_Value(A)), m_Value(NotA)),
2558-
m_Value(B))) &&
2554+
if (match(X, m_c_Or(m_CombineAnd(m_Not(m_Value(A)), m_Value(NotA)),
2555+
m_Value(B))) &&
25592556
match(Y, m_c_And(m_Specific(A), m_Specific(B))))
25602557
return NotA;
25612558

llvm/lib/IR/Constants.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ bool Constant::isElementWiseEqual(Value *Y) const {
316316
Constant *C0 = ConstantExpr::getBitCast(const_cast<Constant *>(this), IntTy);
317317
Constant *C1 = ConstantExpr::getBitCast(cast<Constant>(Y), IntTy);
318318
Constant *CmpEq = ConstantExpr::getICmp(ICmpInst::ICMP_EQ, C0, C1);
319-
return isa<UndefValue>(CmpEq) || match(CmpEq, m_One());
319+
return isa<PoisonValue>(CmpEq) || match(CmpEq, m_One());
320320
}
321321

322322
static bool

llvm/test/Transforms/InstCombine/abs-1.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,14 @@ define <2 x i8> @abs_canonical_2(<2 x i8> %x) {
6363
ret <2 x i8> %abs
6464
}
6565

66-
; Even if a constant has undef elements.
66+
; Even if a constant has poison elements.
6767

68-
define <2 x i8> @abs_canonical_2_vec_undef_elts(<2 x i8> %x) {
69-
; CHECK-LABEL: @abs_canonical_2_vec_undef_elts(
68+
define <2 x i8> @abs_canonical_2_vec_poison_elts(<2 x i8> %x) {
69+
; CHECK-LABEL: @abs_canonical_2_vec_poison_elts(
7070
; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)
7171
; CHECK-NEXT: ret <2 x i8> [[ABS]]
7272
;
73-
%cmp = icmp sgt <2 x i8> %x, <i8 undef, i8 -1>
73+
%cmp = icmp sgt <2 x i8> %x, <i8 poison, i8 -1>
7474
%neg = sub <2 x i8> zeroinitializer, %x
7575
%abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg
7676
ret <2 x i8> %abs
@@ -208,15 +208,15 @@ define <2 x i8> @nabs_canonical_2(<2 x i8> %x) {
208208
ret <2 x i8> %abs
209209
}
210210

211-
; Even if a constant has undef elements.
211+
; Even if a constant has poison elements.
212212

213-
define <2 x i8> @nabs_canonical_2_vec_undef_elts(<2 x i8> %x) {
214-
; CHECK-LABEL: @nabs_canonical_2_vec_undef_elts(
213+
define <2 x i8> @nabs_canonical_2_vec_poison_elts(<2 x i8> %x) {
214+
; CHECK-LABEL: @nabs_canonical_2_vec_poison_elts(
215215
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)
216216
; CHECK-NEXT: [[ABS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
217217
; CHECK-NEXT: ret <2 x i8> [[ABS]]
218218
;
219-
%cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 undef>
219+
%cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 poison>
220220
%neg = sub <2 x i8> zeroinitializer, %x
221221
%abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x
222222
ret <2 x i8> %abs

llvm/test/Transforms/InstCombine/masked-merge-add.ll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
5151
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
5252
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1>
5353
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
54-
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
54+
; CHECK-NEXT: [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]]
5555
; CHECK-NEXT: ret <3 x i32> [[RET]]
5656
;
5757
%and = and <3 x i32> %x, %m
@@ -61,6 +61,21 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
6161
ret <3 x i32> %ret
6262
}
6363

64+
define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {
65+
; CHECK-LABEL: @p_vec_poison(
66+
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
67+
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1>
68+
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
69+
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
70+
; CHECK-NEXT: ret <3 x i32> [[RET]]
71+
;
72+
%and = and <3 x i32> %x, %m
73+
%neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1>
74+
%and1 = and <3 x i32> %neg, %y
75+
%ret = add <3 x i32> %and, %and1
76+
ret <3 x i32> %ret
77+
}
78+
6479
; ============================================================================ ;
6580
; Constant mask.
6681
; ============================================================================ ;

llvm/test/Transforms/InstCombine/masked-merge-or.ll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
5151
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
5252
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1>
5353
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
54-
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
54+
; CHECK-NEXT: [[RET:%.*]] = or <3 x i32> [[AND]], [[AND1]]
5555
; CHECK-NEXT: ret <3 x i32> [[RET]]
5656
;
5757
%and = and <3 x i32> %x, %m
@@ -61,6 +61,21 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
6161
ret <3 x i32> %ret
6262
}
6363

64+
define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {
65+
; CHECK-LABEL: @p_vec_poison(
66+
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
67+
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1>
68+
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
69+
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
70+
; CHECK-NEXT: ret <3 x i32> [[RET]]
71+
;
72+
%and = and <3 x i32> %x, %m
73+
%neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1>
74+
%and1 = and <3 x i32> %neg, %y
75+
%ret = or <3 x i32> %and, %and1
76+
ret <3 x i32> %ret
77+
}
78+
6479
; ============================================================================ ;
6580
; Constant mask.
6681
; ============================================================================ ;

llvm/test/Transforms/InstCombine/masked-merge-xor.ll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
5151
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
5252
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1>
5353
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
54-
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
54+
; CHECK-NEXT: [[RET:%.*]] = xor <3 x i32> [[AND]], [[AND1]]
5555
; CHECK-NEXT: ret <3 x i32> [[RET]]
5656
;
5757
%and = and <3 x i32> %x, %m
@@ -61,6 +61,21 @@ define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m)
6161
ret <3 x i32> %ret
6262
}
6363

64+
define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {
65+
; CHECK-LABEL: @p_vec_poison(
66+
; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
67+
; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1>
68+
; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
69+
; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
70+
; CHECK-NEXT: ret <3 x i32> [[RET]]
71+
;
72+
%and = and <3 x i32> %x, %m
73+
%neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1>
74+
%and1 = and <3 x i32> %neg, %y
75+
%ret = xor <3 x i32> %and, %and1
76+
ret <3 x i32> %ret
77+
}
78+
6479
; ============================================================================ ;
6580
; Constant mask.
6681
; ============================================================================ ;

llvm/test/Transforms/InstSimplify/AndOrXor.ll

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ define i8 @and0(i8 %x) {
1212
ret i8 %r
1313
}
1414

15-
define <2 x i8> @and0_vec_undef_elt(<2 x i8> %x) {
16-
; CHECK-LABEL: @and0_vec_undef_elt(
15+
define <2 x i8> @and0_vec_poison_elt(<2 x i8> %x) {
16+
; CHECK-LABEL: @and0_vec_poison_elt(
1717
; CHECK-NEXT: ret <2 x i8> zeroinitializer
1818
;
19-
%r = and <2 x i8> %x, <i8 undef, i8 0>
19+
%r = and <2 x i8> %x, <i8 poison, i8 0>
2020
ret <2 x i8> %r
2121
}
2222

@@ -31,14 +31,14 @@ define <2 x i32> @add_nsw_signbit(<2 x i32> %x) {
3131
ret <2 x i32> %z
3232
}
3333

34-
; Undef elements in either constant vector are ok.
34+
; Poison elements in either constant vector are ok.
3535

36-
define <2 x i32> @add_nsw_signbit_undef(<2 x i32> %x) {
37-
; CHECK-LABEL: @add_nsw_signbit_undef(
36+
define <2 x i32> @add_nsw_signbit_poison(<2 x i32> %x) {
37+
; CHECK-LABEL: @add_nsw_signbit_poison(
3838
; CHECK-NEXT: ret <2 x i32> [[X:%.*]]
3939
;
40-
%y = xor <2 x i32> %x, <i32 undef, i32 -2147483648>
41-
%z = add nsw <2 x i32> %y, <i32 -2147483648, i32 undef>
40+
%y = xor <2 x i32> %x, <i32 poison, i32 -2147483648>
41+
%z = add nsw <2 x i32> %y, <i32 -2147483648, i32 poison>
4242
ret <2 x i32> %z
4343
}
4444

@@ -53,14 +53,14 @@ define <2 x i5> @add_nuw_signbit(<2 x i5> %x) {
5353
ret <2 x i5> %z
5454
}
5555

56-
; Undef elements in either constant vector are ok.
56+
; Poison elements in either constant vector are ok.
5757

58-
define <2 x i5> @add_nuw_signbit_undef(<2 x i5> %x) {
59-
; CHECK-LABEL: @add_nuw_signbit_undef(
58+
define <2 x i5> @add_nuw_signbit_poison(<2 x i5> %x) {
59+
; CHECK-LABEL: @add_nuw_signbit_poison(
6060
; CHECK-NEXT: ret <2 x i5> [[X:%.*]]
6161
;
62-
%y = xor <2 x i5> %x, <i5 -16, i5 undef>
63-
%z = add nuw <2 x i5> %y, <i5 undef, i5 -16>
62+
%y = xor <2 x i5> %x, <i5 -16, i5 poison>
63+
%z = add nuw <2 x i5> %y, <i5 poison, i5 -16>
6464
ret <2 x i5> %z
6565
}
6666

@@ -584,7 +584,7 @@ define <2 x i32> @or_xor_andn_commute2(<2 x i32> %a, <2 x i32> %b) {
584584
; CHECK-NEXT: ret <2 x i32> [[XOR]]
585585
;
586586
%xor = xor <2 x i32> %a, %b
587-
%neg = xor <2 x i32> %b, <i32 -1, i32 undef>
587+
%neg = xor <2 x i32> %b, <i32 -1, i32 poison>
588588
%and = and <2 x i32> %a, %neg
589589
%or = or <2 x i32> %xor, %and
590590
ret <2 x i32> %or
@@ -708,15 +708,13 @@ define <2 x i32> @or_xorn_and_commute2_undef(<2 x i32> %a, <2 x i32> %b) {
708708
ret <2 x i32> %or
709709
}
710710

711-
; TODO: Unlike the above test, this is safe to fold.
711+
; Unlike the above test, this is safe to fold.
712712

713713
define <2 x i32> @or_xorn_and_commute2_poison(<2 x i32> %a, <2 x i32> %b) {
714714
; CHECK-LABEL: @or_xorn_and_commute2_poison(
715715
; CHECK-NEXT: [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 poison, i32 -1>
716-
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[B:%.*]], [[A]]
717-
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[B]], [[NEGA]]
718-
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[XOR]], [[AND]]
719-
; CHECK-NEXT: ret <2 x i32> [[OR]]
716+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[B:%.*]], [[NEGA]]
717+
; CHECK-NEXT: ret <2 x i32> [[XOR]]
720718
;
721719
%nega = xor <2 x i32> %a, <i32 poison, i32 -1>
722720
%and = and <2 x i32> %b, %a

0 commit comments

Comments
 (0)