Skip to content

Commit e633e7e

Browse files
committed
[InstCombine] fold icmp of select with constants and invertible op
Proof: https://alive2.llvm.org/ce/z/5K6q5z Closes #146642
1 parent 65c071f commit e633e7e

File tree

2 files changed

+144
-50
lines changed

2 files changed

+144
-50
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4332,6 +4332,98 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
43324332
return nullptr;
43334333
}
43344334

4335+
/// If the APInt C has the same invertible function with Operator RefOp in Pred,
4336+
/// return the operands of the function corresponding to each input. Otherwise,
4337+
/// return std::nullopt. This is equivalent to saying that Op1 pred Op2 is true
4338+
/// exactly when the specified pair of RefOp pred C is true.
4339+
/// alive2: https://alive2.llvm.org/ce/z/4jniEb
4340+
static std::optional<std::pair<Value *, Value *>>
4341+
getInvertibleOperandsWithPredicte(const Operator *RefOp, const APInt C,
4342+
CmpInst::Predicate Pred) {
4343+
APInt Op1C;
4344+
// for BinaryOperator just handle RefOp with constant Operand(1)
4345+
if (isa<BinaryOperator>(RefOp)) {
4346+
if (isa<ConstantInt>(RefOp->getOperand(1)))
4347+
Op1C = cast<ConstantInt>(RefOp->getOperand(1))->getValue();
4348+
else
4349+
return std::nullopt;
4350+
}
4351+
4352+
auto getOperands = [&](APInt A) -> auto {
4353+
return std::make_pair(RefOp->getOperand(0),
4354+
ConstantInt::get(RefOp->getOperand(0)->getType(), A));
4355+
};
4356+
switch (RefOp->getOpcode()) {
4357+
default:
4358+
break;
4359+
case Instruction::Or:
4360+
if (cast<PossiblyDisjointInst>(RefOp)->isDisjoint() && ((C & Op1C) == Op1C))
4361+
return getOperands(C ^ Op1C);
4362+
break;
4363+
case Instruction::Add: {
4364+
// TODO: add/sub could support nsw/nuw for scmp/ucmp
4365+
if (CmpInst::isEquality(Pred))
4366+
return getOperands(C - Op1C);
4367+
break;
4368+
}
4369+
case Instruction::Xor: {
4370+
if (CmpInst::isEquality(Pred))
4371+
return getOperands(C ^ Op1C);
4372+
break;
4373+
}
4374+
case Instruction::Sub: {
4375+
if (CmpInst::isEquality(Pred))
4376+
return getOperands(C + Op1C);
4377+
break;
4378+
}
4379+
// alive2: https://alive2.llvm.org/ce/z/WPQznV
4380+
case Instruction::Shl: {
4381+
// Z = shl nsw X, Y <=> X = ashr exact Z, Y
4382+
// Z = shl nuw X, Y <=> X = lshr exact Z, Y
4383+
if (C.ashr(Op1C).shl(Op1C) == C) {
4384+
auto *OBO1 = cast<OverflowingBinaryOperator>(RefOp);
4385+
if (OBO1->hasNoSignedWrap())
4386+
return getOperands(C.ashr(Op1C));
4387+
else if (OBO1->hasNoUnsignedWrap() && !ICmpInst::isSigned(Pred))
4388+
return getOperands(C.lshr(Op1C));
4389+
}
4390+
break;
4391+
}
4392+
case Instruction::AShr: {
4393+
// Z = ashr exact X, Y <=> X = shl nsw Z, Y
4394+
auto *PEO1 = cast<PossiblyExactOperator>(RefOp);
4395+
if (PEO1->isExact() && C.shl(Op1C).ashr(Op1C) == C)
4396+
return getOperands(C.shl(Op1C));
4397+
break;
4398+
}
4399+
case Instruction::LShr: {
4400+
// Z = lshr exact X, Y <=> X = shl nuw Z, Y
4401+
auto *PEO1 = cast<PossiblyExactOperator>(RefOp);
4402+
if (PEO1->isExact() && C.shl(Op1C).lshr(Op1C) == C &&
4403+
!ICmpInst::isSigned(Pred))
4404+
return getOperands(C.shl(Op1C));
4405+
break;
4406+
}
4407+
case Instruction::SExt: {
4408+
unsigned NumBits = RefOp->getType()->getScalarSizeInBits();
4409+
unsigned NumBitsOp0 =
4410+
RefOp->getOperand(0)->getType()->getScalarSizeInBits();
4411+
if (C.trunc(NumBitsOp0).sext(NumBits) == C)
4412+
return getOperands(C.trunc(NumBitsOp0));
4413+
break;
4414+
}
4415+
case Instruction::ZExt: {
4416+
unsigned NumBits = RefOp->getType()->getScalarSizeInBits();
4417+
unsigned NumBitsOp0 =
4418+
RefOp->getOperand(0)->getType()->getScalarSizeInBits();
4419+
if (C.trunc(NumBitsOp0).zext(NumBits) == C && !ICmpInst::isSigned(Pred))
4420+
return getOperands(C.trunc(NumBitsOp0));
4421+
break;
4422+
}
4423+
}
4424+
return std::nullopt;
4425+
}
4426+
43354427
Instruction *InstCombinerImpl::foldSelectICmp(CmpPredicate Pred, SelectInst *SI,
43364428
Value *RHS, const ICmpInst &I) {
43374429
// Try to fold the comparison into the select arms, which will cause the
@@ -4391,6 +4483,24 @@ Instruction *InstCombinerImpl::foldSelectICmp(CmpPredicate Pred, SelectInst *SI,
43914483
return SelectInst::Create(SI->getOperand(0), Op1, Op2);
43924484
}
43934485

4486+
// fold select with constants and invertible op
4487+
Value *Cond;
4488+
const APInt *C1, *C2;
4489+
auto *RHSOp = dyn_cast<Operator>(RHS);
4490+
if (RHSOp &&
4491+
match(SI, m_OneUse(m_Select(m_Value(Cond), m_APInt(C1), m_APInt(C2))))) {
4492+
if (auto Values0 = getInvertibleOperandsWithPredicte(RHSOp, *C1, Pred)) {
4493+
if (auto Values1 = getInvertibleOperandsWithPredicte(RHSOp, *C2, Pred)) {
4494+
assert(Values0->first == Values1->first &&
4495+
"Invertible Operand0 mismatch");
4496+
auto *NewSI = Builder.CreateSelect(Cond, Values0->second,
4497+
Values1->second, SI->getName());
4498+
return ICmpInst::Create(Instruction::ICmp, I.getPredicate(), NewSI,
4499+
Values0->first, I.getName());
4500+
}
4501+
}
4502+
}
4503+
43944504
return nullptr;
43954505
}
43964506

llvm/test/Transforms/InstCombine/icmp-select-operator-constant.ll

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
define i1 @shl_nsw_scmp(i8 %a, i1 %cond) {
77
; CHECK-LABEL: define i1 @shl_nsw_scmp(
88
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
9-
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
10-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 16
11-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A_SHL]], [[SEL]]
9+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 1, i8 2
10+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL1]], [[A]]
1211
; CHECK-NEXT: ret i1 [[CMP]]
1312
;
1413
%a_shl = shl nsw i8 %a, 3
@@ -20,9 +19,8 @@ define i1 @shl_nsw_scmp(i8 %a, i1 %cond) {
2019
define i1 @c_shl_nsw_scmp(i8 %a, i1 %cond) {
2120
; CHECK-LABEL: define i1 @c_shl_nsw_scmp(
2221
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
23-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 16
24-
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
25-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL]], [[A_SHL]]
22+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 1, i8 2
23+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL1]], [[A]]
2624
; CHECK-NEXT: ret i1 [[CMP]]
2725
;
2826
%sel = select i1 %cond, i8 8, i8 16
@@ -48,9 +46,8 @@ define i1 @shl_nsw_scmp_mismatch(i8 %a, i1 %cond) {
4846
define i1 @shl_nsw_ucmp(i8 %a, i1 %cond) {
4947
; CHECK-LABEL: define i1 @shl_nsw_ucmp(
5048
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
51-
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
52-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 24
53-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A_SHL]], [[SEL]]
49+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 1, i8 3
50+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SEL1]], [[A]]
5451
; CHECK-NEXT: ret i1 [[CMP]]
5552
;
5653
%a_shl = shl nsw i8 %a, 3
@@ -64,9 +61,8 @@ define i1 @shl_nsw_ucmp(i8 %a, i1 %cond) {
6461
define i1 @shl_nuw_ucmp(i8 %a, i1 %cond) {
6562
; CHECK-LABEL: define i1 @shl_nuw_ucmp(
6663
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
67-
; CHECK-NEXT: [[A_SHL:%.*]] = shl nuw i8 [[A]], 3
68-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 32
69-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A_SHL]], [[SEL]]
64+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 1, i8 4
65+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[SEL1]], [[A]]
7066
; CHECK-NEXT: ret i1 [[CMP]]
7167
;
7268
%a_shl = shl nuw i8 %a, 3
@@ -79,9 +75,8 @@ define i1 @shl_nuw_ucmp(i8 %a, i1 %cond) {
7975
define i1 @shl_nuw_eqcmp(i8 %a, i1 %cond) {
8076
; CHECK-LABEL: define i1 @shl_nuw_eqcmp(
8177
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
82-
; CHECK-NEXT: [[A_SHL:%.*]] = shl nuw i8 [[A]], 3
83-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 64
84-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SEL]], [[A_SHL]]
78+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 1, i8 8
79+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SEL1]], [[A]]
8580
; CHECK-NEXT: ret i1 [[CMP]]
8681
;
8782
%a_shl = shl nuw i8 %a, 3
@@ -110,9 +105,8 @@ define i1 @shl_nuw_scmp(i8 %a, i1 %cond) {
110105
define i1 @ashr_exact_ucmp(i8 %a, i1 %cond) {
111106
; CHECK-LABEL: define i1 @ashr_exact_ucmp(
112107
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
113-
; CHECK-NEXT: [[A_SHL:%.*]] = ashr exact i8 [[A]], 2
114-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 12, i8 4
115-
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[A_SHL]], [[SEL]]
108+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 48, i8 16
109+
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[SEL1]], [[A]]
116110
; CHECK-NEXT: ret i1 [[CMP]]
117111
;
118112
%a_shl = ashr exact i8 %a, 2
@@ -124,9 +118,8 @@ define i1 @ashr_exact_ucmp(i8 %a, i1 %cond) {
124118
define i1 @ashr_exact_scmp(i8 %a, i1 %cond) {
125119
; CHECK-LABEL: define i1 @ashr_exact_scmp(
126120
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
127-
; CHECK-NEXT: [[A_SHL:%.*]] = ashr exact i8 [[A]], 2
128-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 4
129-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A_SHL]], [[SEL]]
121+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 32, i8 16
122+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL1]], [[A]]
130123
; CHECK-NEXT: ret i1 [[CMP]]
131124
;
132125
%a_shl = ashr exact i8 %a, 2
@@ -140,9 +133,8 @@ define i1 @ashr_exact_scmp(i8 %a, i1 %cond) {
140133
define i1 @lshr_exact_ucmp(i8 %a, i1 %cond) {
141134
; CHECK-LABEL: define i1 @lshr_exact_ucmp(
142135
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
143-
; CHECK-NEXT: [[A_SHL:%.*]] = lshr exact i8 [[A]], 1
144-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 1, i8 3
145-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i8 [[A_SHL]], [[SEL]]
136+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 2, i8 6
137+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SEL1]], [[A]]
146138
; CHECK-NEXT: ret i1 [[CMP]]
147139
;
148140
%a_shl = lshr exact i8 %a, 1
@@ -154,9 +146,8 @@ define i1 @lshr_exact_ucmp(i8 %a, i1 %cond) {
154146
define i1 @lshr_exact_scmp(i8 %a, i1 %cond) {
155147
; CHECK-LABEL: define i1 @lshr_exact_scmp(
156148
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
157-
; CHECK-NEXT: [[A_SHL:%.*]] = lshr exact i8 [[A]], 1
158-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 1, i8 3
159-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign uge i8 [[A_SHL]], [[SEL]]
149+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 2, i8 6
150+
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[SEL1]], [[A]]
160151
; CHECK-NEXT: ret i1 [[CMP]]
161152
;
162153
%a_shl = lshr exact i8 %a, 1
@@ -170,9 +161,8 @@ define i1 @lshr_exact_scmp(i8 %a, i1 %cond) {
170161
define i1 @zext_ucmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
171162
; CHECK-LABEL: define i1 @zext_ucmp(
172163
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
173-
; CHECK-NEXT: [[IDX:%.*]] = zext i8 [[A]] to i16
174-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 128, i16 64
175-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i16 [[SEL]], [[IDX]]
164+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 -128, i8 64
165+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SEL1]], [[A]]
176166
; CHECK-NEXT: ret i1 [[CMP]]
177167
;
178168
%idx = zext i8 %a to i16
@@ -184,9 +174,8 @@ define i1 @zext_ucmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
184174
define i1 @zext_scmp_mismatch(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
185175
; CHECK-LABEL: define i1 @zext_scmp_mismatch(
186176
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
187-
; CHECK-NEXT: [[IDX:%.*]] = zext i8 [[A]] to i16
188-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 128, i16 64
189-
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i16 [[SEL]], [[IDX]]
177+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 -128, i8 64
178+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SEL1]], [[A]]
190179
; CHECK-NEXT: ret i1 [[CMP]]
191180
;
192181
%idx = zext i8 %a to i16
@@ -200,9 +189,8 @@ define i1 @zext_scmp_mismatch(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
200189
define i1 @sext_ucmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
201190
; CHECK-LABEL: define i1 @sext_ucmp(
202191
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
203-
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[A]] to i16
204-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 -127, i16 126
205-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[SEL]], [[IDX]]
192+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 -127, i8 126
193+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[SEL1]], [[A]]
206194
; CHECK-NEXT: ret i1 [[CMP]]
207195
;
208196
%idx = sext i8 %a to i16
@@ -228,9 +216,8 @@ define i1 @sext_ucmp_mismatch(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
228216
define i1 @sext_scmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
229217
; CHECK-LABEL: define i1 @sext_scmp(
230218
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
231-
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[A]] to i16
232-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 -5, i16 9
233-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[SEL]], [[IDX]]
219+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 -5, i8 9
220+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL1]], [[A]]
234221
; CHECK-NEXT: ret i1 [[CMP]]
235222
;
236223
%idx = sext i8 %a to i16
@@ -244,9 +231,8 @@ define i1 @sext_scmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
244231
define i1 @or_disjoint_ucmp(i8 %a, i1 %cond) {
245232
; CHECK-LABEL: define i1 @or_disjoint_ucmp(
246233
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
247-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[A]], 3
248-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 11, i8 7
249-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[OR]], [[SEL]]
234+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 8, i8 4
235+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[SEL1]], [[A]]
250236
; CHECK-NEXT: ret i1 [[CMP]]
251237
;
252238
%or = or disjoint i8 %a, 3
@@ -258,9 +244,8 @@ define i1 @or_disjoint_ucmp(i8 %a, i1 %cond) {
258244
define i1 @or_disjoint_scmp(i8 %a, i1 %cond) {
259245
; CHECK-LABEL: define i1 @or_disjoint_scmp(
260246
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
261-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[A]], 3
262-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 11, i8 7
263-
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[OR]], [[SEL]]
247+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 8, i8 4
248+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[SEL1]], [[A]]
264249
; CHECK-NEXT: ret i1 [[CMP]]
265250
;
266251
%or = or disjoint i8 %a, 3
@@ -288,7 +273,7 @@ define i1 @sub_eq(i8 %a, i1 %cond) {
288273
; CHECK-LABEL: define i1 @sub_eq(
289274
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
290275
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i8 4, i8 12
291-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[TMP1]]
276+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], [[A]]
292277
; CHECK-NEXT: ret i1 [[CMP]]
293278
;
294279
%sub = sub i8 %a, 5
@@ -317,7 +302,7 @@ define i1 @add_ne(i8 %a, i1 %cond) {
317302
; CHECK-LABEL: define i1 @add_ne(
318303
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
319304
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i8 -6, i8 2
320-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A]], [[TMP1]]
305+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], [[A]]
321306
; CHECK-NEXT: ret i1 [[CMP]]
322307
;
323308
%sub = add i8 %a, 5
@@ -330,9 +315,8 @@ define i1 @add_ne(i8 %a, i1 %cond) {
330315
define i1 @xor_eq(i8 %a, i1 %cond) {
331316
; CHECK-LABEL: define i1 @xor_eq(
332317
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
333-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 -1, i8 7
334-
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[SEL]]
335-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 5
318+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND]], i8 -6, i8 2
319+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SEL1]], [[A]]
336320
; CHECK-NEXT: ret i1 [[CMP]]
337321
;
338322
%sub = xor i8 %a, 5

0 commit comments

Comments
 (0)