Skip to content

Commit c485e50

Browse files
committed
SCEV: teach isImpliedViaOperations about samesign
Use CmpPredicate::getMatching in isImpliedCondBalancedTypes to pass samesign information to isImpliedViaOperations, and teach it to call CmpPredicate::getPreferredSignedPredicate, effectively making it optimize with samesign information.
1 parent 57e945e commit c485e50

File tree

4 files changed

+37
-28
lines changed

4 files changed

+37
-28
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11860,15 +11860,13 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
1186011860
}
1186111861

1186211862
// Check whether the found predicate is the same as the desired predicate.
11863-
// FIXME: use CmpPredicate::getMatching here.
11864-
if (FoundPred == static_cast<CmpInst::Predicate>(Pred))
11865-
return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI);
11863+
if (auto P = CmpPredicate::getMatching(FoundPred, Pred))
11864+
return isImpliedCondOperands(*P, LHS, RHS, FoundLHS, FoundRHS, CtxI);
1186611865

1186711866
// Check whether swapping the found predicate makes it the same as the
1186811867
// desired predicate.
11869-
// FIXME: use CmpPredicate::getMatching here.
11870-
if (ICmpInst::getSwappedCmpPredicate(FoundPred) ==
11871-
static_cast<CmpInst::Predicate>(Pred)) {
11868+
if (auto P = CmpPredicate::getMatching(
11869+
ICmpInst::getSwappedCmpPredicate(FoundPred), Pred)) {
1187211870
// We can write the implication
1187311871
// 0. LHS Pred RHS <- FoundLHS SwapPred FoundRHS
1187411872
// using one of the following ways:
@@ -11879,22 +11877,23 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
1187911877
// Forms 1. and 2. require swapping the operands of one condition. Don't
1188011878
// do this if it would break canonical constant/addrec ordering.
1188111879
if (!isa<SCEVConstant>(RHS) && !isa<SCEVAddRecExpr>(LHS))
11882-
return isImpliedCondOperands(FoundPred, RHS, LHS, FoundLHS, FoundRHS,
11883-
CtxI);
11880+
return isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(*P), RHS,
11881+
LHS, FoundLHS, FoundRHS, CtxI);
1188411882
if (!isa<SCEVConstant>(FoundRHS) && !isa<SCEVAddRecExpr>(FoundLHS))
11885-
return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, CtxI);
11883+
return isImpliedCondOperands(*P, LHS, RHS, FoundRHS, FoundLHS, CtxI);
1188611884

1188711885
// There's no clear preference between forms 3. and 4., try both. Avoid
1188811886
// forming getNotSCEV of pointer values as the resulting subtract is
1188911887
// not legal.
1189011888
if (!LHS->getType()->isPointerTy() && !RHS->getType()->isPointerTy() &&
11891-
isImpliedCondOperands(FoundPred, getNotSCEV(LHS), getNotSCEV(RHS),
11892-
FoundLHS, FoundRHS, CtxI))
11889+
isImpliedCondOperands(ICmpInst::getSwappedCmpPredicate(*P),
11890+
getNotSCEV(LHS), getNotSCEV(RHS), FoundLHS,
11891+
FoundRHS, CtxI))
1189311892
return true;
1189411893

1189511894
if (!FoundLHS->getType()->isPointerTy() &&
1189611895
!FoundRHS->getType()->isPointerTy() &&
11897-
isImpliedCondOperands(Pred, LHS, RHS, getNotSCEV(FoundLHS),
11896+
isImpliedCondOperands(*P, LHS, RHS, getNotSCEV(FoundLHS),
1189811897
getNotSCEV(FoundRHS), CtxI))
1189911898
return true;
1190011899

@@ -12564,14 +12563,16 @@ bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
1256412563
return false;
1256512564

1256612565
// We only want to work with GT comparison so far.
12567-
if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT) {
12566+
if (ICmpInst::isLT(Pred)) {
1256812567
Pred = ICmpInst::getSwappedCmpPredicate(Pred);
1256912568
std::swap(LHS, RHS);
1257012569
std::swap(FoundLHS, FoundRHS);
1257112570
}
1257212571

12572+
CmpInst::Predicate P = Pred.getPreferredSignedPredicate();
12573+
1257312574
// For unsigned, try to reduce it to corresponding signed comparison.
12574-
if (Pred == ICmpInst::ICMP_UGT)
12575+
if (P == ICmpInst::ICMP_UGT)
1257512576
// We can replace unsigned predicate with its signed counterpart if all
1257612577
// involved values are non-negative.
1257712578
// TODO: We could have better support for unsigned.
@@ -12584,10 +12585,10 @@ bool ScalarEvolution::isImpliedViaOperations(CmpPredicate Pred, const SCEV *LHS,
1258412585
FoundRHS) &&
1258512586
isImpliedCondOperands(ICmpInst::ICMP_SGT, RHS, MinusOne, FoundLHS,
1258612587
FoundRHS))
12587-
Pred = ICmpInst::ICMP_SGT;
12588+
P = ICmpInst::ICMP_SGT;
1258812589
}
1258912590

12590-
if (Pred != ICmpInst::ICMP_SGT)
12591+
if (P != ICmpInst::ICMP_SGT)
1259112592
return false;
1259212593

1259312594
auto GetOpFromSExt = [&](const SCEV *S) {

llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) {
66
; CHECK-LABEL: 'exit_count_samesign'
77
; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign
8-
; CHECK-NEXT: Loop %inner.loop: backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
8+
; CHECK-NEXT: Loop %inner.loop: backedge-taken count is {(-2 + %iter.count),+,-1}<nw><%outer.loop>
99
; CHECK-NEXT: Loop %inner.loop: constant max backedge-taken count is i32 2147483646
10-
; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
10+
; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is {(-2 + %iter.count),+,-1}<nw><%outer.loop>
1111
; CHECK-NEXT: Loop %inner.loop: Trip multiple is 1
1212
; CHECK-NEXT: Loop %outer.loop: <multiple exits> Unpredictable backedge-taken count.
1313
; CHECK-NEXT: Loop %outer.loop: Unpredictable constant max backedge-taken count.

llvm/test/Analysis/ScalarEvolution/implied-via-division.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ define void @implied1_samesign(i32 %n) {
3131
; Prove that (n > 1) ===> (n / 2 s> 0).
3232
; CHECK-LABEL: 'implied1_samesign'
3333
; CHECK-NEXT: Determining loop execution counts for: @implied1_samesign
34-
; CHECK-NEXT: Loop %header: backedge-taken count is (-1 + (1 smax %n.div.2))<nsw>
34+
; CHECK-NEXT: Loop %header: backedge-taken count is (-1 + %n.div.2)<nsw>
3535
; CHECK-NEXT: Loop %header: constant max backedge-taken count is i32 1073741822
36-
; CHECK-NEXT: Loop %header: symbolic max backedge-taken count is (-1 + (1 smax %n.div.2))<nsw>
36+
; CHECK-NEXT: Loop %header: symbolic max backedge-taken count is (-1 + %n.div.2)<nsw>
3737
; CHECK-NEXT: Loop %header: Trip multiple is 1
3838
;
3939
entry:

llvm/test/Transforms/IndVarSimplify/iv-ext-samesign.ll

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,32 @@ define i32 @iv_zext_zext_gt_slt(i32 %iter.count, ptr %ptr) {
6868
; CHECK-LABEL: define i32 @iv_zext_zext_gt_slt(
6969
; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
7070
; CHECK-NEXT: [[ENTRY:.*]]:
71-
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
71+
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[ITER_COUNT]], -1
7272
; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
7373
; CHECK: [[PH_LOOPEXIT:.*]]:
7474
; CHECK-NEXT: br label %[[PH:.*]]
7575
; CHECK: [[PH]]:
76+
; CHECK-NEXT: [[INDVARS_IV_NEXT3:%.*]] = add i32 [[INDVARS_IV1:%.*]], -1
7677
; CHECK-NEXT: br label %[[OUTER_LOOP]]
7778
; CHECK: [[OUTER_LOOP]]:
78-
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
79-
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
79+
; CHECK-NEXT: [[INDVARS_IV1]] = phi i32 [ [[INDVARS_IV_NEXT3]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
80+
; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ [[IV_OUTER_1:%.*]], %[[PH]] ], [ [[ITER_COUNT]], %[[ENTRY]] ]
81+
; CHECK-NEXT: [[IV_OUTER_1]] = add nsw i32 [[IV_OUTER]], -1
82+
; CHECK-NEXT: [[INDVARS_IV_NEXT2:%.*]] = zext nneg i32 [[IV_OUTER_1]] to i64
8083
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
8184
; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
82-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], 1
85+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[IV_OUTER]], 1
8386
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
8487
; CHECK: [[INNER_LOOP_PREHEADER]]:
88+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64
8589
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
8690
; CHECK: [[INNER_LOOP]]:
8791
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
8892
; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
8993
; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
9094
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
91-
; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
92-
; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
95+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
96+
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
9397
; CHECK: [[EXIT:.*:]]
9498
; CHECK-NEXT: ret i32 0
9599
;
@@ -424,28 +428,32 @@ define i32 @iv_sext_sext_gt_slt(i32 %iter.count, ptr %ptr) {
424428
; CHECK-LABEL: define i32 @iv_sext_sext_gt_slt(
425429
; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
426430
; CHECK-NEXT: [[ENTRY:.*]]:
431+
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[ITER_COUNT]], -1
427432
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
428433
; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
429434
; CHECK: [[PH_LOOPEXIT:.*]]:
430435
; CHECK-NEXT: br label %[[PH:.*]]
431436
; CHECK: [[PH]]:
437+
; CHECK-NEXT: [[INDVARS_IV_NEXT3:%.*]] = add i32 [[INDVARS_IV2:%.*]], -1
432438
; CHECK-NEXT: br label %[[OUTER_LOOP]]
433439
; CHECK: [[OUTER_LOOP]]:
434440
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
441+
; CHECK-NEXT: [[INDVARS_IV2]] = phi i32 [ [[INDVARS_IV_NEXT3]], %[[PH]] ], [ [[TMP1]], %[[ENTRY]] ]
435442
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
436443
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
437444
; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
438445
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], 1
439446
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
440447
; CHECK: [[INNER_LOOP_PREHEADER]]:
448+
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV2]] to i64
441449
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
442450
; CHECK: [[INNER_LOOP]]:
443451
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
444452
; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
445453
; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
446454
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
447-
; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
448-
; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
455+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
456+
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
449457
; CHECK: [[EXIT:.*:]]
450458
; CHECK-NEXT: ret i32 0
451459
;

0 commit comments

Comments
 (0)