Skip to content

Commit c3b8bd1

Browse files
committed
[InstCombine] Always try to invert non-canonical predicate of an icmp
Summary: The actual transform i was going after was: https://rise4fun.com/Alive/Tp9H ``` Name: zz Pre: isPowerOf2(C0) && isPowerOf2(C1) && C1 == C0 %t0 = and i8 %x, C0 %r = icmp eq i8 %t0, C1 => %t = icmp eq i8 %t0, 0 %r = xor i1 %t, -1 Name: zz Pre: isPowerOf2(C0) %t0 = and i8 %x, C0 %r = icmp ne i8 %t0, 0 => %t = icmp eq i8 %t0, 0 %r = xor i1 %t, -1 ``` but as it can be seen from the current tests, we already canonicalize most of it, and we are only missing handling multi-use non-canonical icmp predicates. If we have both `!=0` and `==0`, even though we can CSE them, we end up being stuck with them. We should canonicalize to the `==0`. I believe this is one of the cleanup steps i'll need after `-scalarizer` if i end up proceeding with my WIP alloca promotion helper pass. Reviewers: spatel, jdoerfert, nikic Reviewed By: nikic Subscribers: zzheng, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D83139
1 parent ef70cc9 commit c3b8bd1

File tree

13 files changed

+307
-272
lines changed

13 files changed

+307
-272
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5283,6 +5283,47 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) {
52835283
return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
52845284
}
52855285

5286+
/// If we have a comparison with a non-canonical predicate, if we can update
5287+
/// all the users, invert the predicate and adjust all the users.
5288+
static CmpInst *canonicalizeICmpPredicate(CmpInst &I) {
5289+
// Is the predicate already canonical?
5290+
CmpInst::Predicate Pred = I.getPredicate();
5291+
if (isCanonicalPredicate(Pred))
5292+
return nullptr;
5293+
5294+
// Can all users be adjusted to predicate inversion?
5295+
if (!canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
5296+
return nullptr;
5297+
5298+
// Ok, we can canonicalize comparison!
5299+
// Let's first invert the comparison's predicate.
5300+
I.setPredicate(CmpInst::getInversePredicate(Pred));
5301+
I.setName(I.getName() + ".not");
5302+
5303+
// And now let's adjust every user.
5304+
for (User *U : I.users()) {
5305+
switch (cast<Instruction>(U)->getOpcode()) {
5306+
case Instruction::Select: {
5307+
auto *SI = cast<SelectInst>(U);
5308+
SI->swapValues();
5309+
SI->swapProfMetadata();
5310+
break;
5311+
}
5312+
case Instruction::Br:
5313+
cast<BranchInst>(U)->swapSuccessors(); // swaps prof metadata too
5314+
break;
5315+
case Instruction::Xor:
5316+
U->replaceAllUsesWith(&I);
5317+
break;
5318+
default:
5319+
llvm_unreachable("Got unexpected user - out of sync with "
5320+
"canFreelyInvertAllUsersOf() ?");
5321+
}
5322+
}
5323+
5324+
return &I;
5325+
}
5326+
52865327
/// Integer compare with boolean values can always be turned into bitwise ops.
52875328
static Instruction *canonicalizeICmpBool(ICmpInst &I,
52885329
InstCombiner::BuilderTy &Builder) {
@@ -5521,8 +5562,11 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
55215562
if (Instruction *Res = canonicalizeICmpBool(I, Builder))
55225563
return Res;
55235564

5524-
if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I))
5525-
return NewICmp;
5565+
if (Instruction *Res = canonicalizeCmpWithConstant(I))
5566+
return Res;
5567+
5568+
if (Instruction *Res = canonicalizeICmpPredicate(I))
5569+
return Res;
55265570

55275571
if (Instruction *Res = foldICmpWithConstant(I))
55285572
return Res;

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,23 @@ static inline bool isFreeToInvert(Value *V, bool WillInvertAllUses) {
215215
}
216216

217217
/// Given i1 V, can every user of V be freely adapted if V is changed to !V ?
218+
/// InstCombine's canonicalizeICmpPredicate() must be kept in sync with this fn.
218219
///
219220
/// See also: isFreeToInvert()
220221
static inline bool canFreelyInvertAllUsersOf(Value *V, Value *IgnoredUser) {
221222
// Look at every user of V.
222-
for (User *U : V->users()) {
223-
if (U == IgnoredUser)
223+
for (Use &U : V->uses()) {
224+
if (U.getUser() == IgnoredUser)
224225
continue; // Don't consider this user.
225226

226-
auto *I = cast<Instruction>(U);
227+
auto *I = cast<Instruction>(U.getUser());
227228
switch (I->getOpcode()) {
228229
case Instruction::Select:
230+
if (U.getOperandNo() != 0) // Only if the value is used as select cond.
231+
return false;
232+
break;
229233
case Instruction::Br:
234+
assert(U.getOperandNo() == 0 && "Must be branching on that value.");
230235
break; // Free to invert by swapping true/false values/destinations.
231236
case Instruction::Xor: // Can invert 'xor' if it's a 'not', by ignoring it.
232237
if (!match(I, m_Not(m_Value())))

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,21 +2532,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
25322532
if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))
25332533
return I;
25342534

2535-
// Canonicalize a one-use integer compare with a non-canonical predicate by
2536-
// inverting the predicate and swapping the select operands. This matches a
2537-
// compare canonicalization for conditional branches.
2538-
// TODO: Should we do the same for FP compares?
25392535
CmpInst::Predicate Pred;
2540-
if (match(CondVal, m_OneUse(m_ICmp(Pred, m_Value(), m_Value()))) &&
2541-
!isCanonicalPredicate(Pred)) {
2542-
// Swap true/false values and condition.
2543-
CmpInst *Cond = cast<CmpInst>(CondVal);
2544-
Cond->setPredicate(CmpInst::getInversePredicate(Pred));
2545-
SI.swapValues();
2546-
SI.swapProfMetadata();
2547-
Worklist.push(Cond);
2548-
return &SI;
2549-
}
25502536

25512537
if (SelType->isIntOrIntVectorTy(1) &&
25522538
TrueVal->getType() == CondVal->getType()) {

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,9 +2755,9 @@ Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
27552755
return replaceOperand(
27562756
BI, 0, ConstantInt::getFalse(BI.getCondition()->getType()));
27572757

2758-
// Canonicalize, for example, icmp_ne -> icmp_eq or fcmp_one -> fcmp_oeq.
2758+
// Canonicalize, for example, fcmp_one -> fcmp_oeq.
27592759
CmpInst::Predicate Pred;
2760-
if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())),
2760+
if (match(&BI, m_Br(m_OneUse(m_FCmp(Pred, m_Value(), m_Value())),
27612761
m_BasicBlock(), m_BasicBlock())) &&
27622762
!isCanonicalPredicate(Pred)) {
27632763
// Swap destinations and condition.

llvm/test/ThinLTO/X86/cfi-devirt.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ cont2:
110110

111111
; Check that traps are conditional. Invalid TYPE_ID can cause
112112
; unconditional traps.
113-
; CHECK-IR: br i1 {{.*}}, label %trap
113+
; CHECK-IR: br i1 {{.*}}, label %trap, label %cont2
114114

115115
; We still have to call it as virtual.
116-
; CHECK-IR: %call3 = tail call i32 %8
116+
; CHECK-IR: %call3 = tail call i32 %7
117117
%call3 = tail call i32 %8(%struct.A* nonnull %obj, i32 %call)
118118
ret i32 %call3
119119
}

llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ declare void @use1(i1)
88
define i8 @p0(i8 %x, i8 %v0, i8 %v1) {
99
; CHECK-LABEL: @p0(
1010
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
11-
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
12-
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0
11+
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
12+
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0
1313
; CHECK-NEXT: ret i8 [[R]]
1414
;
1515
%t0 = and i8 %x, 1
@@ -20,8 +20,8 @@ define i8 @p0(i8 %x, i8 %v0, i8 %v1) {
2020
define i8 @p1(i8 %x, i8 %v0, i8 %v1) {
2121
; CHECK-LABEL: @p1(
2222
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
23-
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
24-
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]]
23+
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
24+
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
2525
; CHECK-NEXT: ret i8 [[R]]
2626
;
2727
%t0 = and i8 %x, 1
@@ -51,14 +51,14 @@ define i8 @t3(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out, i1 %c) {
5151
; CHECK-LABEL: @t3(
5252
; CHECK-NEXT: bb0:
5353
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
54-
; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0
54+
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
5555
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
5656
; CHECK: bb1:
57-
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
57+
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
5858
; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1
5959
; CHECK-NEXT: br label [[BB2]]
6060
; CHECK: bb2:
61-
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]]
61+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
6262
; CHECK-NEXT: ret i8 [[R1]]
6363
;
6464
bb0:
@@ -76,10 +76,10 @@ bb2:
7676
define i8 @t4(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out) {
7777
; CHECK-LABEL: @t4(
7878
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
79-
; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0
80-
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
79+
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
80+
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
8181
; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1
82-
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]]
82+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
8383
; CHECK-NEXT: ret i8 [[R1]]
8484
;
8585
%t0 = and i8 %x, 1
@@ -112,8 +112,8 @@ define i8 @n6(i8 %x, i8 %v0, i8 %v1) {
112112
define i8 @n7(i8 %x, i8 %v0, i8 %v1) {
113113
; CHECK-LABEL: @n7(
114114
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
115-
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
116-
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
115+
; CHECK-NEXT: [[T1_NOT_NOT:%.*]] = icmp eq i8 [[T0]], 0
116+
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT_NOT]], i8 [[V0:%.*]], i8 [[V1:%.*]]
117117
; CHECK-NEXT: ret i8 [[R]]
118118
;
119119
%t0 = and i8 %x, 1

llvm/test/Transforms/InstCombine/icmp-mul-zext.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ define i32 @sterix(i32, i8, i64) {
1313
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], [[SH_PROM]]
1414
; CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[SHR]] to i64
1515
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw nsw i64 [[CONV]], [[CONV2]]
16-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i64 [[MUL3]], 4294967295
17-
; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
16+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[MUL3]], 4294967296
17+
; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
1818
; CHECK: lor.rhs:
1919
; CHECK-NEXT: [[AND:%.*]] = and i64 [[MUL3]], [[TMP2]]
2020
; CHECK-NEXT: [[CONV4:%.*]] = trunc i64 [[AND]] to i32
21-
; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq i32 [[CONV4]], 0
22-
; CHECK-NEXT: [[PHI_CAST:%.*]] = zext i1 [[TOBOOL7]] to i32
21+
; CHECK-NEXT: [[TOBOOL7_NOT:%.*]] = icmp eq i32 [[CONV4]], 0
22+
; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7_NOT]] to i32
2323
; CHECK-NEXT: br label [[LOR_END]]
2424
; CHECK: lor.end:
25-
; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHI_CAST]], [[LOR_RHS]] ]
25+
; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHITMP]], [[LOR_RHS]] ]
2626
; CHECK-NEXT: ret i32 [[TMP4]]
2727
;
2828
entry:

llvm/test/Transforms/InstCombine/logical-select.ll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {
1919

2020
define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
2121
; CHECK-LABEL: @bar(
22-
; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
23-
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E]], i32 [[C:%.*]], i32 [[D:%.*]]
22+
; CHECK-NEXT: [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
23+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
2424
; CHECK-NEXT: ret i32 [[TMP1]]
2525
;
2626
%e = icmp slt i32 %a, %b
@@ -69,8 +69,8 @@ define i32 @fold_inverted_icmp_preds(i32 %a, i32 %b, i32 %c, i32 %d) {
6969
; CHECK-LABEL: @fold_inverted_icmp_preds(
7070
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
7171
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0
72-
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
73-
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 [[D:%.*]]
72+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
73+
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]]
7474
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
7575
; CHECK-NEXT: ret i32 [[OR]]
7676
;
@@ -88,8 +88,8 @@ define i32 @fold_inverted_icmp_preds_reverse(i32 %a, i32 %b, i32 %c, i32 %d) {
8888
; CHECK-LABEL: @fold_inverted_icmp_preds_reverse(
8989
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
9090
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]]
91-
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
92-
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0
91+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
92+
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 0
9393
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
9494
; CHECK-NEXT: ret i32 [[OR]]
9595
;
@@ -124,8 +124,8 @@ define i32 @fold_inverted_fcmp_preds(float %a, float %b, i32 %c, i32 %d) {
124124

125125
define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) {
126126
; CHECK-LABEL: @fold_inverted_icmp_vector_preds(
127-
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]
128-
; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]
127+
; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]
128+
; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]
129129
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]]
130130
; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer
131131
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]]
@@ -535,9 +535,9 @@ define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c)
535535

536536
define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {
537537
; CHECK-LABEL: @allSignBits(
538-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[COND:%.*]], -1
539-
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[FVAL:%.*]], i32 [[TVAL:%.*]]
540-
; CHECK-NEXT: ret i32 [[TMP2]]
538+
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp slt i32 [[COND:%.*]], 0
539+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i32 [[TVAL:%.*]], i32 [[FVAL:%.*]]
540+
; CHECK-NEXT: ret i32 [[TMP1]]
541541
;
542542
%bitmask = ashr i32 %cond, 31
543543
%not_bitmask = xor i32 %bitmask, -1
@@ -549,9 +549,9 @@ define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {
549549

550550
define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) {
551551
; CHECK-LABEL: @allSignBits_vec(
552-
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1>
553-
; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]]
554-
; CHECK-NEXT: ret <4 x i8> [[TMP2]]
552+
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1>
553+
; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[DOTNOT]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]]
554+
; CHECK-NEXT: ret <4 x i8> [[TMP1]]
555555
;
556556
%bitmask = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7>
557557
%not_bitmask = xor <4 x i8> %bitmask, <i8 -1, i8 -1, i8 -1, i8 -1>

0 commit comments

Comments
 (0)