Skip to content

Commit ba69e1d

Browse files
committed
[SCEV] Preserve divisor info when adding guard info for ICMP_NE via Sub. (llvm#163250)
Follow-up to llvm#160500 to preserve divisibiltiy info when creating the UMax. PR: llvm#163250 (cherry picked from commit eb17a8d)
1 parent 98e17c6 commit ba69e1d

File tree

4 files changed

+272
-33
lines changed

4 files changed

+272
-33
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15426,6 +15426,23 @@ void ScalarEvolution::LoopGuards::collectFromPHI(
1542615426
}
1542715427
}
1542815428

15429+
// Return a new SCEV that modifies \p Expr to the closest number divides by
15430+
// \p Divisor and greater or equal than Expr. For now, only handle constant
15431+
// Expr.
15432+
static const SCEV *getNextSCEVDividesByDivisor(const SCEV *Expr,
15433+
const APInt &DivisorVal,
15434+
ScalarEvolution &SE) {
15435+
const APInt *ExprVal;
15436+
if (!match(Expr, m_scev_APInt(ExprVal)) || ExprVal->isNegative() ||
15437+
DivisorVal.isNonPositive())
15438+
return Expr;
15439+
APInt Rem = ExprVal->urem(DivisorVal);
15440+
if (Rem.isZero())
15441+
return Expr;
15442+
// return the SCEV: Expr + Divisor - Expr % Divisor
15443+
return SE.getConstant(*ExprVal + DivisorVal - Rem);
15444+
}
15445+
1542915446
void ScalarEvolution::LoopGuards::collectFromBlock(
1543015447
ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
1543115448
const BasicBlock *Block, const BasicBlock *Pred,
@@ -15499,22 +15516,6 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1549915516
return false;
1550015517
};
1550115518

15502-
// Return a new SCEV that modifies \p Expr to the closest number divides by
15503-
// \p Divisor and greater or equal than Expr. For now, only handle constant
15504-
// Expr.
15505-
auto GetNextSCEVDividesByDivisor = [&](const SCEV *Expr,
15506-
const APInt &DivisorVal) {
15507-
const APInt *ExprVal;
15508-
if (!match(Expr, m_scev_APInt(ExprVal)) || ExprVal->isNegative() ||
15509-
DivisorVal.isNonPositive())
15510-
return Expr;
15511-
APInt Rem = ExprVal->urem(DivisorVal);
15512-
if (Rem.isZero())
15513-
return Expr;
15514-
// return the SCEV: Expr + Divisor - Expr % Divisor
15515-
return SE.getConstant(*ExprVal + DivisorVal - Rem);
15516-
};
15517-
1551815519
// Return a new SCEV that modifies \p Expr to the closest number divides by
1551915520
// \p Divisor and less or equal than Expr. For now, only handle constant
1552015521
// Expr.
@@ -15551,7 +15552,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1555115552
"Expected non-negative operand!");
1555215553
auto *DivisibleExpr =
1555315554
IsMin ? GetPreviousSCEVDividesByDivisor(MinMaxLHS, DivisorVal)
15554-
: GetNextSCEVDividesByDivisor(MinMaxLHS, DivisorVal);
15555+
: getNextSCEVDividesByDivisor(MinMaxLHS, DivisorVal, SE);
1555515556
SmallVector<const SCEV *> Ops = {
1555615557
ApplyDivisibiltyOnMinMaxExpr(MinMaxRHS, Divisor), DivisibleExpr};
1555715558
return SE.getMinMaxExpr(SCTy, Ops);
@@ -15634,15 +15635,15 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1563415635
case CmpInst::ICMP_UGT:
1563515636
case CmpInst::ICMP_SGT:
1563615637
RHS = SE.getAddExpr(RHS, One);
15637-
RHS = GetNextSCEVDividesByDivisor(RHS, DividesBy);
15638+
RHS = getNextSCEVDividesByDivisor(RHS, DividesBy, SE);
1563815639
break;
1563915640
case CmpInst::ICMP_ULE:
1564015641
case CmpInst::ICMP_SLE:
1564115642
RHS = GetPreviousSCEVDividesByDivisor(RHS, DividesBy);
1564215643
break;
1564315644
case CmpInst::ICMP_UGE:
1564415645
case CmpInst::ICMP_SGE:
15645-
RHS = GetNextSCEVDividesByDivisor(RHS, DividesBy);
15646+
RHS = getNextSCEVDividesByDivisor(RHS, DividesBy, SE);
1564615647
break;
1564715648
default:
1564815649
break;
@@ -15696,7 +15697,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1569615697
case CmpInst::ICMP_NE:
1569715698
if (match(RHS, m_scev_Zero())) {
1569815699
const SCEV *OneAlignedUp =
15699-
GetNextSCEVDividesByDivisor(One, DividesBy);
15700+
getNextSCEVDividesByDivisor(One, DividesBy, SE);
1570015701
To = SE.getUMaxExpr(FromRewritten, OneAlignedUp);
1570115702
} else {
1570215703
// LHS != RHS can be rewritten as (LHS - RHS) = UMax(1, LHS - RHS),
@@ -15922,8 +15923,11 @@ const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
1592215923
if (MatchBinarySub(S, LHS, RHS)) {
1592315924
if (LHS > RHS)
1592415925
std::swap(LHS, RHS);
15925-
if (NotEqual.contains({LHS, RHS}))
15926-
return SE.getUMaxExpr(S, SE.getOne(S->getType()));
15926+
if (NotEqual.contains({LHS, RHS})) {
15927+
const SCEV *OneAlignedUp = getNextSCEVDividesByDivisor(
15928+
SE.getOne(S->getType()), SE.getConstantMultiple(S), SE);
15929+
return SE.getUMaxExpr(OneAlignedUp, S);
15930+
}
1592715931
}
1592815932
return nullptr;
1592915933
};

llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ define void @ptr_induction_early_exit_eq_1_with_align_on_load(ptr %a, ptr %b, pt
14311431
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
14321432
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
14331433
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
1434-
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
1434+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693950
14351435
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
14361436
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
14371437
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
@@ -1470,7 +1470,7 @@ define void @ptr_induction_early_exit_eq_1_with_align_on_arguments(ptr align 8 %
14701470
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
14711471
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
14721472
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
1473-
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
1473+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693950
14741474
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
14751475
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
14761476
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
@@ -1511,7 +1511,7 @@ define void @ptr_induction_early_exit_eq_1_align_assumption_1(ptr %a, ptr %b, pt
15111511
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
15121512
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
15131513
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
1514-
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
1514+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693950
15151515
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
15161516
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
15171517
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
@@ -1556,7 +1556,7 @@ define void @ptr_induction_early_exit_eq_1_align_assumption_2(ptr %a, ptr %b, pt
15561556
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
15571557
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
15581558
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
1559-
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
1559+
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693950
15601560
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
15611561
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
15621562
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)

llvm/test/Transforms/LoopUnroll/scevunroll.ll

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -439,20 +439,18 @@ declare void @fn(i32)
439439
define void @peel_int_eq_condition(i32 %start) {
440440
; CHECK-LABEL: @peel_int_eq_condition(
441441
; CHECK-NEXT: entry:
442-
; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[START:%.*]], i32 100)
443-
; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[SMAX]], 1
444442
; CHECK-NEXT: br label [[LOOP_PEEL_BEGIN:%.*]]
445443
; CHECK: loop.peel.begin:
446444
; CHECK-NEXT: br label [[LOOP_PEEL:%.*]]
447445
; CHECK: loop.peel:
448-
; CHECK-NEXT: [[C_0_PEEL:%.*]] = icmp eq i32 [[START]], [[START]]
446+
; CHECK-NEXT: [[C_0_PEEL:%.*]] = icmp eq i32 [[START:%.*]], [[START]]
449447
; CHECK-NEXT: br i1 [[C_0_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[LOOP_LATCH_PEEL:%.*]]
450448
; CHECK: if.then.peel:
451449
; CHECK-NEXT: call void @fn(i32 [[START]])
452450
; CHECK-NEXT: br label [[LOOP_LATCH_PEEL]]
453451
; CHECK: loop.latch.peel:
454452
; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add i32 [[START]], 1
455-
; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i32 [[IV_NEXT_PEEL]], [[TMP0]]
453+
; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp slt i32 [[START]], 100
456454
; CHECK-NEXT: br i1 [[EXITCOND_PEEL]], label [[LOOP_PEEL_NEXT:%.*]], label [[EXIT:%.*]]
457455
; CHECK: loop.peel.next:
458456
; CHECK-NEXT: br label [[LOOP_PEEL_NEXT1:%.*]]
@@ -467,9 +465,9 @@ define void @peel_int_eq_condition(i32 %start) {
467465
; CHECK-NEXT: call void @fn(i32 [[IV]])
468466
; CHECK-NEXT: br label [[LOOP_LATCH]]
469467
; CHECK: loop.latch:
470-
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
471-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
472-
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
468+
; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
469+
; CHECK-NEXT: [[EC:%.*]] = icmp slt i32 [[IV]], 100
470+
; CHECK-NEXT: br i1 [[EC]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
473471
; CHECK: exit.loopexit:
474472
; CHECK-NEXT: br label [[EXIT]]
475473
; CHECK: exit:

0 commit comments

Comments
 (0)