Skip to content

Commit 3d199d0

Browse files
committed
[InstSimplify] Make simplifyWithOpReplaced() recursive (PR63104)
Support replacement of operands not only in the immediate instruction, but also instructions it uses. To the most part, this extension is straightforward, but there are two bits worth highlighting: First, we can now no longer assume that if the Op is a vector, the instruction also returns a vector. If Op is a vector and the instruction returns a scalar, we should consider it as a cross-lane operation. Second, for the x ^ x special case, we can no longer assume that the operand is RepOp, as we might have a replacement higher up the instruction chain. There is one optimization regression, but it is in a fuzzer-generated test case. Fixes llvm#63104.
1 parent ed68282 commit 3d199d0

File tree

6 files changed

+62
-73
lines changed

6 files changed

+62
-73
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,12 +4256,15 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
42564256
if (V == Op)
42574257
return RepOp;
42584258

4259+
if (!MaxRecurse--)
4260+
return nullptr;
4261+
42594262
// We cannot replace a constant, and shouldn't even try.
42604263
if (isa<Constant>(Op))
42614264
return nullptr;
42624265

42634266
auto *I = dyn_cast<Instruction>(V);
4264-
if (!I || !is_contained(I->operands(), Op))
4267+
if (!I)
42654268
return nullptr;
42664269

42674270
// The arguments of a phi node might refer to a value from a previous
@@ -4272,15 +4275,26 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
42724275
if (Op->getType()->isVectorTy()) {
42734276
// For vector types, the simplification must hold per-lane, so forbid
42744277
// potentially cross-lane operations like shufflevector.
4275-
assert(I->getType()->isVectorTy() && "Vector type mismatch");
4276-
if (isa<ShuffleVectorInst>(I) || isa<CallBase>(I))
4278+
if (!I->getType()->isVectorTy() || isa<ShuffleVectorInst>(I) ||
4279+
isa<CallBase>(I))
42774280
return nullptr;
42784281
}
42794282

42804283
// Replace Op with RepOp in instruction operands.
4281-
SmallVector<Value *, 8> NewOps(I->getNumOperands());
4282-
transform(I->operands(), NewOps.begin(),
4283-
[&](Value *V) { return V == Op ? RepOp : V; });
4284+
SmallVector<Value *, 8> NewOps;
4285+
bool AnyReplaced = false;
4286+
for (Value *InstOp : I->operands()) {
4287+
if (Value *NewInstOp = simplifyWithOpReplaced(
4288+
InstOp, Op, RepOp, Q, AllowRefinement, MaxRecurse)) {
4289+
NewOps.push_back(NewInstOp);
4290+
AnyReplaced = InstOp != NewInstOp;
4291+
} else {
4292+
NewOps.push_back(InstOp);
4293+
}
4294+
}
4295+
4296+
if (!AnyReplaced)
4297+
return nullptr;
42844298

42854299
if (!AllowRefinement) {
42864300
// General InstSimplify functions may refine the result, e.g. by returning
@@ -4305,10 +4319,8 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43054319
// by assumption and this case never wraps, so nowrap flags can be
43064320
// ignored.
43074321
if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&
4308-
NewOps[0] == NewOps[1]) {
4309-
assert(NewOps[0] == RepOp && "Precondition for non-poison assumption");
4322+
NewOps[0] == RepOp && NewOps[1] == RepOp)
43104323
return Constant::getNullValue(I->getType());
4311-
}
43124324

43134325
// If we are substituting an absorber constant into a binop and extra
43144326
// poison can't leak if we remove the select -- because both operands of
@@ -4328,7 +4340,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43284340
if (NewOps.size() == 2 && match(NewOps[1], m_Zero()))
43294341
return NewOps[0];
43304342
}
4331-
} else if (MaxRecurse) {
4343+
} else {
43324344
// The simplification queries below may return the original value. Consider:
43334345
// %div = udiv i32 %arg, %arg2
43344346
// %mul = mul nsw i32 %div, %arg2
@@ -4343,7 +4355,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43434355
};
43444356

43454357
return PreventSelfSimplify(
4346-
::simplifyInstructionWithOperands(I, NewOps, Q, MaxRecurse - 1));
4358+
::simplifyInstructionWithOperands(I, NewOps, Q, MaxRecurse));
43474359
}
43484360

43494361
// If all operands are constant after substituting Op for RepOp then we can

llvm/test/Transforms/InstCombine/div-by-0-guard-before-smul_ov-not.ll

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ define i1 @n2_wrong_size(i4 %size0, i4 %size1, i4 %nmemb) {
5353

5454
define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) {
5555
; CHECK-LABEL: @n3_wrong_pred(
56-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0
57-
; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]])
58-
; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1
59-
; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[SMUL_OV]], true
60-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i1 true, i1 [[PHITMP]]
61-
; CHECK-NEXT: ret i1 [[OR]]
56+
; CHECK-NEXT: ret i1 true
6257
;
6358
%cmp = icmp ne i4 %size, 0 ; not 'eq'
6459
%smul = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 %size, i4 %nmemb)
@@ -71,11 +66,7 @@ define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) {
7166
define i1 @n4_not_and(i4 %size, i4 %nmemb) {
7267
; CHECK-LABEL: @n4_not_and(
7368
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0
74-
; CHECK-NEXT: [[SMUL:%.*]] = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]])
75-
; CHECK-NEXT: [[SMUL_OV:%.*]] = extractvalue { i4, i1 } [[SMUL]], 1
76-
; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[SMUL_OV]], true
77-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i1 [[PHITMP]], i1 false
78-
; CHECK-NEXT: ret i1 [[OR]]
69+
; CHECK-NEXT: ret i1 [[CMP]]
7970
;
8071
%cmp = icmp eq i4 %size, 0
8172
%smul = tail call { i4, i1 } @llvm.smul.with.overflow.i4(i4 %size, i4 %nmemb)

llvm/test/Transforms/InstCombine/div-by-0-guard-before-umul_ov-not.ll

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ define i1 @n2_wrong_size(i4 %size0, i4 %size1, i4 %nmemb) {
5353

5454
define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) {
5555
; CHECK-LABEL: @n3_wrong_pred(
56-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i4 [[SIZE:%.*]], 0
57-
; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]])
58-
; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1
59-
; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true
60-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i1 true, i1 [[PHITMP]]
61-
; CHECK-NEXT: ret i1 [[OR]]
56+
; CHECK-NEXT: ret i1 true
6257
;
6358
%cmp = icmp ne i4 %size, 0 ; not 'eq'
6459
%umul = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 %size, i4 %nmemb)
@@ -71,11 +66,7 @@ define i1 @n3_wrong_pred(i4 %size, i4 %nmemb) {
7166
define i1 @n4_not_and(i4 %size, i4 %nmemb) {
7267
; CHECK-LABEL: @n4_not_and(
7368
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i4 [[SIZE:%.*]], 0
74-
; CHECK-NEXT: [[UMUL:%.*]] = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 [[SIZE]], i4 [[NMEMB:%.*]])
75-
; CHECK-NEXT: [[UMUL_OV:%.*]] = extractvalue { i4, i1 } [[UMUL]], 1
76-
; CHECK-NEXT: [[PHITMP:%.*]] = xor i1 [[UMUL_OV]], true
77-
; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP]], i1 [[PHITMP]], i1 false
78-
; CHECK-NEXT: ret i1 [[OR]]
69+
; CHECK-NEXT: ret i1 [[CMP]]
7970
;
8071
%cmp = icmp eq i4 %size, 0
8172
%umul = tail call { i4, i1 } @llvm.umul.with.overflow.i4(i4 %size, i4 %nmemb)

llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ declare void @use2(i1)
1616

1717
define i32 @select_clz_to_ctz(i32 %a) {
1818
; CHECK-LABEL: @select_clz_to_ctz(
19-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range [[RNG0:![0-9]+]]
20-
; CHECK-NEXT: ret i32 [[COND]]
19+
; CHECK-NEXT: [[SUB1:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range [[RNG0:![0-9]+]]
20+
; CHECK-NEXT: ret i32 [[SUB1]]
2121
;
2222
%sub = sub i32 0, %a
2323
%and = and i32 %sub, %a
@@ -74,8 +74,7 @@ define i32 @select_clz_to_ctz_extra_use(i32 %a) {
7474
; CHECK-LABEL: @select_clz_to_ctz_extra_use(
7575
; CHECK-NEXT: [[SUB1:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range [[RNG0]]
7676
; CHECK-NEXT: call void @use(i32 [[SUB1]])
77-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), !range [[RNG0]]
78-
; CHECK-NEXT: ret i32 [[COND]]
77+
; CHECK-NEXT: ret i32 [[SUB1]]
7978
;
8079
%sub = sub i32 0, %a
8180
%and = and i32 %sub, %a
@@ -89,8 +88,8 @@ define i32 @select_clz_to_ctz_extra_use(i32 %a) {
8988

9089
define i32 @select_clz_to_ctz_and_commuted(i32 %a) {
9190
; CHECK-LABEL: @select_clz_to_ctz_and_commuted(
92-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range [[RNG0]]
93-
; CHECK-NEXT: ret i32 [[COND]]
91+
; CHECK-NEXT: [[SUB1:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range [[RNG0]]
92+
; CHECK-NEXT: ret i32 [[SUB1]]
9493
;
9594
%sub = sub i32 0, %a
9695
%and = and i32 %a, %sub
@@ -105,8 +104,8 @@ define i32 @select_clz_to_ctz_icmp_ne(i32 %a) {
105104
; CHECK-LABEL: @select_clz_to_ctz_icmp_ne(
106105
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[A:%.*]], 0
107106
; CHECK-NEXT: call void @use2(i1 [[TOBOOL]])
108-
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), !range [[RNG0]]
109-
; CHECK-NEXT: ret i32 [[COND]]
107+
; CHECK-NEXT: [[SUB1:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), !range [[RNG0]]
108+
; CHECK-NEXT: ret i32 [[SUB1]]
110109
;
111110
%sub = sub i32 0, %a
112111
%and = and i32 %sub, %a
@@ -120,8 +119,8 @@ define i32 @select_clz_to_ctz_icmp_ne(i32 %a) {
120119

121120
define i64 @select_clz_to_ctz_i64(i64 %a) {
122121
; CHECK-LABEL: @select_clz_to_ctz_i64(
123-
; CHECK-NEXT: [[COND:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 true), !range [[RNG1:![0-9]+]]
124-
; CHECK-NEXT: ret i64 [[COND]]
122+
; CHECK-NEXT: [[SUB1:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 true), !range [[RNG1:![0-9]+]]
123+
; CHECK-NEXT: ret i64 [[SUB1]]
125124
;
126125
%sub = sub i64 0, %a
127126
%and = and i64 %sub, %a
@@ -139,10 +138,8 @@ define i32 @select_clz_to_ctz_wrong_sub(i32 %a) {
139138
; CHECK-NEXT: [[SUB:%.*]] = sub i32 1, [[A:%.*]]
140139
; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[A]]
141140
; CHECK-NEXT: [[LZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[AND]], i1 true), !range [[RNG0]]
142-
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
143141
; CHECK-NEXT: [[SUB1:%.*]] = xor i32 [[LZ]], 31
144-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[LZ]], i32 [[SUB1]]
145-
; CHECK-NEXT: ret i32 [[COND]]
142+
; CHECK-NEXT: ret i32 [[SUB1]]
146143
;
147144
%sub = sub i32 1, %a
148145
%and = and i32 %sub, %a
@@ -159,10 +156,8 @@ define i64 @select_clz_to_ctz_i64_wrong_xor(i64 %a) {
159156
; CHECK-NEXT: [[SUB:%.*]] = sub i64 0, [[A:%.*]]
160157
; CHECK-NEXT: [[AND:%.*]] = and i64 [[SUB]], [[A]]
161158
; CHECK-NEXT: [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), !range [[RNG1]]
162-
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A]], 0
163159
; CHECK-NEXT: [[SUB11:%.*]] = or i64 [[LZ]], 64
164-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB11]]
165-
; CHECK-NEXT: ret i64 [[COND]]
160+
; CHECK-NEXT: ret i64 [[SUB11]]
166161
;
167162
%sub = sub i64 0, %a
168163
%and = and i64 %sub, %a
@@ -175,12 +170,9 @@ define i64 @select_clz_to_ctz_i64_wrong_xor(i64 %a) {
175170

176171
define i64 @select_clz_to_ctz_i64_wrong_icmp_cst(i64 %a) {
177172
; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_icmp_cst(
178-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 0, [[A:%.*]]
179-
; CHECK-NEXT: [[AND:%.*]] = and i64 [[SUB]], [[A]]
180-
; CHECK-NEXT: [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), !range [[RNG1]]
181-
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A]], 1
182-
; CHECK-NEXT: [[SUB1:%.*]] = xor i64 [[LZ]], 63
183-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB1]]
173+
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 1
174+
; CHECK-NEXT: [[SUB1:%.*]] = call i64 @llvm.cttz.i64(i64 [[A]], i1 true), !range [[RNG1]]
175+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 63, i64 [[SUB1]]
184176
; CHECK-NEXT: ret i64 [[COND]]
185177
;
186178
%sub = sub i64 0, %a
@@ -255,8 +247,8 @@ define i4 @PR45762(i3 %x4) {
255247
; CHECK-NEXT: [[T7:%.*]] = zext i3 [[T4]] to i4
256248
; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]
257249
; CHECK-NEXT: [[OR_69_NOT:%.*]] = icmp eq i3 [[X4]], 0
258-
; CHECK-NEXT: [[UMUL_231:%.*]] = select i1 [[OR_69_NOT]], i4 0, i4 [[T7]]
259-
; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_231]]
250+
; CHECK-NEXT: [[UMUL_231:%.*]] = shl i4 [[ONE_HOT_16]], [[T7]]
251+
; CHECK-NEXT: [[SEL_71:%.*]] = select i1 [[OR_69_NOT]], i4 -8, i4 [[UMUL_231]]
260252
; CHECK-NEXT: ret i4 [[SEL_71]]
261253
;
262254
%t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)
@@ -284,8 +276,8 @@ define i4 @PR45762_logical(i3 %x4) {
284276
; CHECK-NEXT: [[T7:%.*]] = zext i3 [[T4]] to i4
285277
; CHECK-NEXT: [[ONE_HOT_16:%.*]] = shl nuw i4 1, [[T7]]
286278
; CHECK-NEXT: [[OR_69_NOT:%.*]] = icmp eq i3 [[X4]], 0
287-
; CHECK-NEXT: [[UMUL_231:%.*]] = select i1 [[OR_69_NOT]], i4 0, i4 [[T7]]
288-
; CHECK-NEXT: [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_231]]
279+
; CHECK-NEXT: [[UMUL_231:%.*]] = shl i4 [[ONE_HOT_16]], [[T7]]
280+
; CHECK-NEXT: [[SEL_71:%.*]] = select i1 [[OR_69_NOT]], i4 -8, i4 [[UMUL_231]]
289281
; CHECK-NEXT: ret i4 [[SEL_71]]
290282
;
291283
%t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,19 @@ define void @ashr_out_of_range(ptr %A) {
17471747
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26135
17481748
define void @ashr_out_of_range_1(ptr %A) {
17491749
; CHECK-LABEL: @ashr_out_of_range_1(
1750+
; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4
1751+
; CHECK-NEXT: [[L_FROZEN:%.*]] = freeze i177 [[L]]
1752+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -1
1753+
; CHECK-NEXT: [[B:%.*]] = select i1 [[TMP1]], i177 0, i177 [[L_FROZEN]]
1754+
; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[B]] to i64
1755+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], -1
1756+
; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP3]]
1757+
; CHECK-NEXT: [[C17:%.*]] = icmp sgt i177 [[B]], [[L_FROZEN]]
1758+
; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[C17]] to i64
1759+
; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP4]]
1760+
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i177 [[L_FROZEN]], -1
1761+
; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP5]], i177 0, i177 [[L_FROZEN]]
1762+
; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 4
17501763
; CHECK-NEXT: ret void
17511764
;
17521765
%L = load i177, ptr %A, align 4

llvm/test/Transforms/InstSimplify/select.ll

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,9 +1094,7 @@ define i8 @select_eq_xor_recursive(i8 %a, i8 %b) {
10941094
; CHECK-LABEL: @select_eq_xor_recursive(
10951095
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]]
10961096
; CHECK-NEXT: [[INV:%.*]] = xor i8 [[XOR]], -1
1097-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[B]]
1098-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -1, i8 [[INV]]
1099-
; CHECK-NEXT: ret i8 [[SEL]]
1097+
; CHECK-NEXT: ret i8 [[INV]]
11001098
;
11011099
%xor = xor i8 %a, %b
11021100
%inv = xor i8 %xor, -1
@@ -1110,9 +1108,7 @@ define i8 @select_eq_xor_recursive2(i8 %a, i8 %b) {
11101108
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A:%.*]], [[B:%.*]]
11111109
; CHECK-NEXT: [[INV:%.*]] = xor i8 [[XOR]], -1
11121110
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[INV]], 10
1113-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[B]]
1114-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 9, i8 [[ADD]]
1115-
; CHECK-NEXT: ret i8 [[SEL]]
1111+
; CHECK-NEXT: ret i8 [[ADD]]
11161112
;
11171113
%xor = xor i8 %a, %b
11181114
%inv = xor i8 %xor, -1
@@ -1162,9 +1158,7 @@ define i8 @select_eq_and_recursive(i8 %a) {
11621158
; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]]
11631159
; CHECK-NEXT: [[AND:%.*]] = and i8 [[NEG]], [[A]]
11641160
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[AND]], 1
1165-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 0
1166-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 1, i8 [[ADD]]
1167-
; CHECK-NEXT: ret i8 [[SEL]]
1161+
; CHECK-NEXT: ret i8 [[ADD]]
11681162
;
11691163
%neg = sub i8 0, %a
11701164
%and = and i8 %neg, %a
@@ -1194,11 +1188,7 @@ define i8 @select_eq_and_recursive_propagates_poison(i8 %a, i8 %b) {
11941188

11951189
define i8 @select_eq_xor_recursive_allow_refinement(i8 %a, i8 %b) {
11961190
; CHECK-LABEL: @select_eq_xor_recursive_allow_refinement(
1197-
; CHECK-NEXT: [[XOR1:%.*]] = add i8 [[A:%.*]], [[B:%.*]]
1198-
; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[A]], [[XOR1]]
1199-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 0
1200-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[XOR2]], i8 0
1201-
; CHECK-NEXT: ret i8 [[SEL]]
1191+
; CHECK-NEXT: ret i8 0
12021192
;
12031193
%xor1 = add i8 %a, %b
12041194
%xor2 = xor i8 %a, %xor1

0 commit comments

Comments
 (0)