Skip to content

Commit acafde0

Browse files
committed
[InstCombine] enhance icmp with sub folds
There were 2 related but over-specified folds for: C1 - X == C One allowed multi-use but was limited to equal constants. The other allowed different constants but disallowed multi-use. This combines the 2 folds into a more general match. The test diffs show the multi-use cases that were falling through the cracks. https://alive2.llvm.org/ce/z/4_hEt2 define i1 @src(i8 %x, i8 %subC, i8 %C) { %s = sub i8 %subC, %x %r = icmp eq i8 %s, %C ret i1 %r } define i1 @tgt(i8 %x, i8 %subC, i8 %C) { %newC = sub i8 %subC, %C %isneg = icmp eq i8 %x, %newC ret i1 %isneg }
1 parent cd76fa7 commit acafde0

File tree

2 files changed

+20
-21
lines changed

2 files changed

+20
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,21 +2579,25 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp,
25792579
const APInt &C) {
25802580
Value *X = Sub->getOperand(0), *Y = Sub->getOperand(1);
25812581
ICmpInst::Predicate Pred = Cmp.getPredicate();
2582-
const APInt *C2;
2583-
APInt SubResult;
2582+
Type *Ty = Sub->getType();
25842583

2585-
// icmp eq/ne (sub C, Y), C -> icmp eq/ne Y, 0
2586-
if (match(X, m_APInt(C2)) && *C2 == C && Cmp.isEquality())
2587-
return new ICmpInst(Cmp.getPredicate(), Y,
2588-
ConstantInt::get(Y->getType(), 0));
2584+
// (SubC - Y) == C) --> Y == (SubC - C)
2585+
// (SubC - Y) != C) --> Y != (SubC - C)
2586+
Constant *SubC;
2587+
if (Cmp.isEquality() && match(X, m_ImmConstant(SubC))) {
2588+
return new ICmpInst(Pred, Y,
2589+
ConstantExpr::getSub(SubC, ConstantInt::get(Ty, C)));
2590+
}
25892591

25902592
// (icmp P (sub nuw|nsw C2, Y), C) -> (icmp swap(P) Y, C2-C)
2593+
const APInt *C2;
2594+
APInt SubResult;
25912595
if (match(X, m_APInt(C2)) &&
25922596
((Cmp.isUnsigned() && Sub->hasNoUnsignedWrap()) ||
25932597
(Cmp.isSigned() && Sub->hasNoSignedWrap())) &&
25942598
!subWithOverflow(SubResult, *C2, C, Cmp.isSigned()))
25952599
return new ICmpInst(Cmp.getSwappedPredicate(), Y,
2596-
ConstantInt::get(Y->getType(), SubResult));
2600+
ConstantInt::get(Ty, SubResult));
25972601

25982602
// The following transforms are only worth it if the only user of the subtract
25992603
// is the icmp.
@@ -3122,12 +3126,7 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
31223126
break;
31233127
case Instruction::Sub:
31243128
if (BO->hasOneUse()) {
3125-
// Only check for constant LHS here, as constant RHS will be canonicalized
3126-
// to add and use the fold above.
3127-
if (Constant *BOC = dyn_cast<Constant>(BOp0)) {
3128-
// Replace ((sub BOC, B) != C) with (B != BOC-C).
3129-
return new ICmpInst(Pred, BOp1, ConstantExpr::getSub(BOC, RHS));
3130-
} else if (C.isZero()) {
3129+
if (C.isZero()) {
31313130
// Replace ((sub A, B) != 0) with (A != B).
31323131
return new ICmpInst(Pred, BOp0, BOp1);
31333132
}

llvm/test/Transforms/InstCombine/icmp-sub.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ define i1 @neg_eq_43(i32 %x) {
204204
; CHECK-LABEL: @neg_eq_43(
205205
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
206206
; CHECK-NEXT: call void @use(i32 [[NEGX]])
207-
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 43
207+
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -43
208208
; CHECK-NEXT: ret i1 [[R]]
209209
;
210210
%negx = sub i32 0, %x
@@ -217,7 +217,7 @@ define i1 @neg_ne_44(i32 %x) {
217217
; CHECK-LABEL: @neg_ne_44(
218218
; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
219219
; CHECK-NEXT: call void @use(i32 [[NEGX]])
220-
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 44
220+
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -44
221221
; CHECK-NEXT: ret i1 [[R]]
222222
;
223223
%negx = sub i32 0, %x
@@ -230,7 +230,7 @@ define i1 @neg_nsw_eq_45(i32 %x) {
230230
; CHECK-LABEL: @neg_nsw_eq_45(
231231
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
232232
; CHECK-NEXT: call void @use(i32 [[NEGX]])
233-
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[NEGX]], 45
233+
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], -45
234234
; CHECK-NEXT: ret i1 [[R]]
235235
;
236236
%negx = sub nsw i32 0, %x
@@ -243,7 +243,7 @@ define i1 @neg_nsw_ne_46(i32 %x) {
243243
; CHECK-LABEL: @neg_nsw_ne_46(
244244
; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
245245
; CHECK-NEXT: call void @use(i32 [[NEGX]])
246-
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[NEGX]], 46
246+
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], -46
247247
; CHECK-NEXT: ret i1 [[R]]
248248
;
249249
%negx = sub nsw i32 0, %x
@@ -256,7 +256,7 @@ define i1 @subC_eq(i32 %x) {
256256
; CHECK-LABEL: @subC_eq(
257257
; CHECK-NEXT: [[SUBX:%.*]] = sub i32 -2147483648, [[X:%.*]]
258258
; CHECK-NEXT: call void @use(i32 [[SUBX]])
259-
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], 43
259+
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483605
260260
; CHECK-NEXT: ret i1 [[R]]
261261
;
262262
%subx = sub i32 -2147483648, %x
@@ -269,7 +269,7 @@ define <2 x i1> @subC_ne(<2 x i8> %x) {
269269
; CHECK-LABEL: @subC_ne(
270270
; CHECK-NEXT: [[SUBX:%.*]] = sub <2 x i8> <i8 -6, i8 -128>, [[X:%.*]]
271271
; CHECK-NEXT: call void @use_vec(<2 x i8> [[SUBX]])
272-
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[SUBX]], <i8 -44, i8 -44>
272+
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], <i8 38, i8 -84>
273273
; CHECK-NEXT: ret <2 x i1> [[R]]
274274
;
275275
%subx = sub <2 x i8> <i8 -6, i8 -128>, %x
@@ -282,7 +282,7 @@ define i1 @subC_nsw_eq(i32 %x) {
282282
; CHECK-LABEL: @subC_nsw_eq(
283283
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -100, [[X:%.*]]
284284
; CHECK-NEXT: call void @use(i32 [[SUBX]])
285-
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUBX]], -2147483648
285+
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], 2147483548
286286
; CHECK-NEXT: ret i1 [[R]]
287287
;
288288
%subx = sub nsw i32 -100, %x
@@ -295,7 +295,7 @@ define i1 @subC_nsw_ne(i32 %x) {
295295
; CHECK-LABEL: @subC_nsw_ne(
296296
; CHECK-NEXT: [[SUBX:%.*]] = sub nsw i32 -2147483647, [[X:%.*]]
297297
; CHECK-NEXT: call void @use(i32 [[SUBX]])
298-
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[SUBX]], 46
298+
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X]], 2147483603
299299
; CHECK-NEXT: ret i1 [[R]]
300300
;
301301
%subx = sub nsw i32 -2147483647, %x

0 commit comments

Comments
 (0)