Skip to content

Commit c1a0135

Browse files
Extend to cover signed comparisons.
1 parent cfcd9df commit c1a0135

File tree

2 files changed

+36
-64
lines changed

2 files changed

+36
-64
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10748,19 +10748,29 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS,
1074810748
if (Depth >= 3)
1074910749
return false;
1075010750

10751-
// (X * Z) icmp (Y * Z) ==> X icmp Y
10752-
// when neither multiply wraps and Z is positive.
1075310751
if (isa<SCEVMulExpr>(LHS) && isa<SCEVMulExpr>(RHS)) {
1075410752
const SCEVMulExpr *LMul = cast<SCEVMulExpr>(LHS);
1075510753
const SCEVMulExpr *RMul = cast<SCEVMulExpr>(RHS);
1075610754

1075710755
if (LMul->getNumOperands() == 2 && RMul->getNumOperands() == 2 &&
10758-
LMul->getOperand(1) == RMul->getOperand(1) &&
10759-
isKnownPositive(LMul->getOperand(1)) && ICmpInst::isUnsigned(Pred) &&
10760-
LMul->hasNoUnsignedWrap() && RMul->hasNoUnsignedWrap()) {
10761-
LHS = LMul->getOperand(0);
10762-
RHS = RMul->getOperand(0);
10763-
Changed = true;
10756+
LMul->getOperand(1) == RMul->getOperand(1)) {
10757+
// (X * Z) uicmp (Y * Z) ==> X uicmp Y
10758+
// when neither multiply wraps and Z is non-zero.
10759+
if (ICmpInst::isUnsigned(Pred) && isKnownNonZero(LMul->getOperand(1)) &&
10760+
LMul->hasNoUnsignedWrap() && RMul->hasNoUnsignedWrap()) {
10761+
LHS = LMul->getOperand(0);
10762+
RHS = RMul->getOperand(0);
10763+
Changed = true;
10764+
}
10765+
// (X * Z) sicmp (Y * Z) ==> X sicmp Y
10766+
// when neither multiply wraps and Z is positive.
10767+
else if (ICmpInst::isSigned(Pred) &&
10768+
isKnownPositive(LMul->getOperand(1)) &&
10769+
LMul->hasNoSignedWrap() && RMul->hasNoSignedWrap()) {
10770+
LHS = LMul->getOperand(0);
10771+
RHS = RMul->getOperand(0);
10772+
Changed = true;
10773+
}
1076410774
}
1076510775
}
1076610776

llvm/test/Analysis/ScalarEvolution/simplify-icmp-ops.ll

Lines changed: 18 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,11 @@
88
define void @signed_icmp_mul_common_multiplicand(ptr %loc) vscale_range(1,1073741824) {
99
; CHECK-LABEL: define void @signed_icmp_mul_common_multiplicand(
1010
; CHECK-SAME: ptr [[LOC:%.*]]) #[[ATTR0:[0-9]+]] {
11-
; CHECK-NEXT: [[ENTRY:.*]]:
12-
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.vscale.i32()
13-
; CHECK-NEXT: [[X:%.*]] = mul nsw i32 9, [[Z]]
14-
; CHECK-NEXT: [[Y:%.*]] = mul nsw i32 5, [[Z]]
11+
; CHECK-NEXT: [[ENTRY:.*:]]
1512
; CHECK-NEXT: br label %[[LOOP:.*]]
1613
; CHECK: [[LOOP]]:
17-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
18-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
19-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
20-
; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X]], [[Y]]
21-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
14+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
15+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
2216
; CHECK: [[EXIT]]:
2317
; CHECK-NEXT: ret void
2418
;
@@ -42,17 +36,11 @@ exit:
4236
define void @signed_icmp_mul_common_multiplicand_commuted(ptr %loc) vscale_range(1,1073741824) {
4337
; CHECK-LABEL: define void @signed_icmp_mul_common_multiplicand_commuted(
4438
; CHECK-SAME: ptr [[LOC:%.*]]) #[[ATTR0]] {
45-
; CHECK-NEXT: [[ENTRY:.*]]:
46-
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.vscale.i32()
47-
; CHECK-NEXT: [[X:%.*]] = mul nsw i32 [[Z]], 9
48-
; CHECK-NEXT: [[Y:%.*]] = mul nsw i32 [[Z]], 5
39+
; CHECK-NEXT: [[ENTRY:.*:]]
4940
; CHECK-NEXT: br label %[[LOOP:.*]]
5041
; CHECK: [[LOOP]]:
51-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
52-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
53-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
54-
; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X]], [[Y]]
55-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
42+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
43+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
5644
; CHECK: [[EXIT]]:
5745
; CHECK-NEXT: ret void
5846
;
@@ -76,18 +64,11 @@ exit:
7664
define void @signed_icmp_mul_common_multiplicand_mixed_arith(ptr %loc) vscale_range(1,1073741824) {
7765
; CHECK-LABEL: define void @signed_icmp_mul_common_multiplicand_mixed_arith(
7866
; CHECK-SAME: ptr [[LOC:%.*]]) #[[ATTR0]] {
79-
; CHECK-NEXT: [[ENTRY:.*]]:
80-
; CHECK-NEXT: [[VS1:%.*]] = call i32 @llvm.vscale.i32()
81-
; CHECK-NEXT: [[VS2:%.*]] = call i32 @llvm.vscale.i32()
82-
; CHECK-NEXT: [[X:%.*]] = mul nsw i32 9, [[VS1]]
83-
; CHECK-NEXT: [[Y:%.*]] = shl nsw i32 [[VS2]], 2
67+
; CHECK-NEXT: [[ENTRY:.*:]]
8468
; CHECK-NEXT: br label %[[LOOP:.*]]
8569
; CHECK: [[LOOP]]:
86-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
87-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
88-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
89-
; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X]], [[Y]]
90-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
70+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
71+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
9172
; CHECK: [[EXIT]]:
9273
; CHECK-NEXT: ret void
9374
;
@@ -212,17 +193,11 @@ exit:
212193
define void @unsigned_icmp_mul_common_multiplicand(ptr %loc) {
213194
; CHECK-LABEL: define void @unsigned_icmp_mul_common_multiplicand(
214195
; CHECK-SAME: ptr [[LOC:%.*]]) {
215-
; CHECK-NEXT: [[ENTRY:.*]]:
216-
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.vscale.i32()
217-
; CHECK-NEXT: [[X:%.*]] = mul nuw i32 9, [[Z]]
218-
; CHECK-NEXT: [[Y:%.*]] = mul nuw i32 5, [[Z]]
196+
; CHECK-NEXT: [[ENTRY:.*:]]
219197
; CHECK-NEXT: br label %[[LOOP:.*]]
220198
; CHECK: [[LOOP]]:
221-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
222-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
223-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
224-
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], [[Y]]
225-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
199+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
200+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
226201
; CHECK: [[EXIT]]:
227202
; CHECK-NEXT: ret void
228203
;
@@ -246,17 +221,11 @@ exit:
246221
define void @unsigned_icmp_mul_common_multiplicand_commuted(ptr %loc) {
247222
; CHECK-LABEL: define void @unsigned_icmp_mul_common_multiplicand_commuted(
248223
; CHECK-SAME: ptr [[LOC:%.*]]) {
249-
; CHECK-NEXT: [[ENTRY:.*]]:
250-
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.vscale.i32()
251-
; CHECK-NEXT: [[X:%.*]] = mul nuw i32 [[Z]], 9
252-
; CHECK-NEXT: [[Y:%.*]] = mul nuw i32 [[Z]], 5
224+
; CHECK-NEXT: [[ENTRY:.*:]]
253225
; CHECK-NEXT: br label %[[LOOP:.*]]
254226
; CHECK: [[LOOP]]:
255-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
256-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
257-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
258-
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], [[Y]]
259-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
227+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
228+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
260229
; CHECK: [[EXIT]]:
261230
; CHECK-NEXT: ret void
262231
;
@@ -280,18 +249,11 @@ exit:
280249
define void @unsigned_icmp_mul_common_multiplicand_mixed_arith(ptr %loc) {
281250
; CHECK-LABEL: define void @unsigned_icmp_mul_common_multiplicand_mixed_arith(
282251
; CHECK-SAME: ptr [[LOC:%.*]]) {
283-
; CHECK-NEXT: [[ENTRY:.*]]:
284-
; CHECK-NEXT: [[VS1:%.*]] = call i32 @llvm.vscale.i32()
285-
; CHECK-NEXT: [[VS2:%.*]] = call i32 @llvm.vscale.i32()
286-
; CHECK-NEXT: [[X:%.*]] = mul nuw i32 9, [[VS1]]
287-
; CHECK-NEXT: [[Y:%.*]] = shl nuw i32 [[VS2]], 2
252+
; CHECK-NEXT: [[ENTRY:.*:]]
288253
; CHECK-NEXT: br label %[[LOOP:.*]]
289254
; CHECK: [[LOOP]]:
290-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IDX_DEC:%.*]], %[[LOOP]] ]
291-
; CHECK-NEXT: store i32 [[IDX]], ptr [[LOC]], align 4
292-
; CHECK-NEXT: [[IDX_DEC]] = add nuw i32 [[IDX]], 1
293-
; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], [[Y]]
294-
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
255+
; CHECK-NEXT: store i32 0, ptr [[LOC]], align 4
256+
; CHECK-NEXT: br i1 false, label %[[LOOP]], label %[[EXIT:.*]]
295257
; CHECK: [[EXIT]]:
296258
; CHECK-NEXT: ret void
297259
;

0 commit comments

Comments
 (0)