Skip to content

Commit b0ea535

Browse files
committed
[SCEV] Use APInt for DividesBy when collecting loop guard info (NFC). (llvm#163017)
Follow-up as suggested in llvm#162617. Just use an APInt for DividesBy, as the existing code already operates on APInt and thus handles the case of DividesBy being 1. PR: llvm#163017 (cherry picked from commit 0d1f2f4)
1 parent 8d201e5 commit b0ea535

File tree

2 files changed

+45
-46
lines changed

2 files changed

+45
-46
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15567,47 +15567,34 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1556715567
return false;
1556815568
};
1556915569

15570-
// Checks whether Expr is a non-negative constant, and Divisor is a positive
15571-
// constant, and returns their APInt in ExprVal and in DivisorVal.
15572-
auto GetNonNegExprAndPosDivisor = [&](const SCEV *Expr, const SCEV *Divisor,
15573-
APInt &ExprVal, APInt &DivisorVal) {
15574-
auto *ConstExpr = dyn_cast<SCEVConstant>(Expr);
15575-
auto *ConstDivisor = dyn_cast<SCEVConstant>(Divisor);
15576-
if (!ConstExpr || !ConstDivisor)
15577-
return false;
15578-
ExprVal = ConstExpr->getAPInt();
15579-
DivisorVal = ConstDivisor->getAPInt();
15580-
return ExprVal.isNonNegative() && !DivisorVal.isNonPositive();
15581-
};
15582-
1558315570
// Return a new SCEV that modifies \p Expr to the closest number divides by
15584-
// \p Divisor and greater or equal than Expr.
15585-
// For now, only handle constant Expr and Divisor.
15571+
// \p Divisor and greater or equal than Expr. For now, only handle constant
15572+
// Expr.
1558615573
auto GetNextSCEVDividesByDivisor = [&](const SCEV *Expr,
15587-
const SCEV *Divisor) {
15588-
APInt ExprVal;
15589-
APInt DivisorVal;
15590-
if (!GetNonNegExprAndPosDivisor(Expr, Divisor, ExprVal, DivisorVal))
15574+
const APInt &DivisorVal) {
15575+
const APInt *ExprVal;
15576+
if (!match(Expr, m_scev_APInt(ExprVal)) || ExprVal->isNegative() ||
15577+
DivisorVal.isNonPositive())
1559115578
return Expr;
15592-
APInt Rem = ExprVal.urem(DivisorVal);
15593-
if (!Rem.isZero())
15594-
// return the SCEV: Expr + Divisor - Expr % Divisor
15595-
return SE.getConstant(ExprVal + DivisorVal - Rem);
15596-
return Expr;
15579+
APInt Rem = ExprVal->urem(DivisorVal);
15580+
if (Rem.isZero())
15581+
return Expr;
15582+
// return the SCEV: Expr + Divisor - Expr % Divisor
15583+
return SE.getConstant(*ExprVal + DivisorVal - Rem);
1559715584
};
1559815585

1559915586
// Return a new SCEV that modifies \p Expr to the closest number divides by
15600-
// \p Divisor and less or equal than Expr.
15601-
// For now, only handle constant Expr and Divisor.
15587+
// \p Divisor and less or equal than Expr. For now, only handle constant
15588+
// Expr.
1560215589
auto GetPreviousSCEVDividesByDivisor = [&](const SCEV *Expr,
15603-
const SCEV *Divisor) {
15604-
APInt ExprVal;
15605-
APInt DivisorVal;
15606-
if (!GetNonNegExprAndPosDivisor(Expr, Divisor, ExprVal, DivisorVal))
15590+
const APInt &DivisorVal) {
15591+
const APInt *ExprVal;
15592+
if (!match(Expr, m_scev_APInt(ExprVal)) || ExprVal->isNegative() ||
15593+
DivisorVal.isNonPositive())
1560715594
return Expr;
15608-
APInt Rem = ExprVal.urem(DivisorVal);
15595+
APInt Rem = ExprVal->urem(DivisorVal);
1560915596
// return the SCEV: Expr - Expr % Divisor
15610-
return SE.getConstant(ExprVal - Rem);
15597+
return SE.getConstant(*ExprVal - Rem);
1561115598
};
1561215599

1561315600
// Apply divisibilty by \p Divisor on MinMaxExpr with constant values,
@@ -15616,6 +15603,11 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1561615603
std::function<const SCEV *(const SCEV *, const SCEV *)>
1561715604
ApplyDivisibiltyOnMinMaxExpr = [&](const SCEV *MinMaxExpr,
1561815605
const SCEV *Divisor) {
15606+
auto *ConstDivisor = dyn_cast<SCEVConstant>(Divisor);
15607+
if (!ConstDivisor)
15608+
return MinMaxExpr;
15609+
const APInt &DivisorVal = ConstDivisor->getAPInt();
15610+
1561915611
const SCEV *MinMaxLHS = nullptr, *MinMaxRHS = nullptr;
1562015612
SCEVTypes SCTy;
1562115613
if (!IsMinMaxSCEVWithNonNegativeConstant(MinMaxExpr, SCTy, MinMaxLHS,
@@ -15626,8 +15618,8 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1562615618
assert(SE.isKnownNonNegative(MinMaxLHS) &&
1562715619
"Expected non-negative operand!");
1562815620
auto *DivisibleExpr =
15629-
IsMin ? GetPreviousSCEVDividesByDivisor(MinMaxLHS, Divisor)
15630-
: GetNextSCEVDividesByDivisor(MinMaxLHS, Divisor);
15621+
IsMin ? GetPreviousSCEVDividesByDivisor(MinMaxLHS, DivisorVal)
15622+
: GetNextSCEVDividesByDivisor(MinMaxLHS, DivisorVal);
1563115623
SmallVector<const SCEV *> Ops = {
1563215624
ApplyDivisibiltyOnMinMaxExpr(MinMaxRHS, Divisor), DivisibleExpr};
1563315625
return SE.getMinMaxExpr(SCTy, Ops);
@@ -15684,10 +15676,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1568415676
};
1568515677

1568615678
const SCEV *RewrittenLHS = GetMaybeRewritten(LHS);
15687-
const SCEV *DividesBy = nullptr;
15688-
const APInt &Multiple = SE.getConstantMultiple(RewrittenLHS);
15689-
if (!Multiple.isOne())
15690-
DividesBy = SE.getConstant(Multiple);
15679+
const APInt &DividesBy = SE.getConstantMultiple(RewrittenLHS);
1569115680

1569215681
// Collect rewrites for LHS and its transitive operands based on the
1569315682
// condition.
@@ -15709,21 +15698,21 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1570915698
[[fallthrough]];
1571015699
case CmpInst::ICMP_SLT: {
1571115700
RHS = SE.getMinusSCEV(RHS, One);
15712-
RHS = DividesBy ? GetPreviousSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15701+
RHS = GetPreviousSCEVDividesByDivisor(RHS, DividesBy);
1571315702
break;
1571415703
}
1571515704
case CmpInst::ICMP_UGT:
1571615705
case CmpInst::ICMP_SGT:
1571715706
RHS = SE.getAddExpr(RHS, One);
15718-
RHS = DividesBy ? GetNextSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15707+
RHS = GetNextSCEVDividesByDivisor(RHS, DividesBy);
1571915708
break;
1572015709
case CmpInst::ICMP_ULE:
1572115710
case CmpInst::ICMP_SLE:
15722-
RHS = DividesBy ? GetPreviousSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15711+
RHS = GetPreviousSCEVDividesByDivisor(RHS, DividesBy);
1572315712
break;
1572415713
case CmpInst::ICMP_UGE:
1572515714
case CmpInst::ICMP_SGE:
15726-
RHS = DividesBy ? GetNextSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15715+
RHS = GetNextSCEVDividesByDivisor(RHS, DividesBy);
1572715716
break;
1572815717
default:
1572915718
break;
@@ -15777,7 +15766,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1577715766
case CmpInst::ICMP_NE:
1577815767
if (match(RHS, m_scev_Zero())) {
1577915768
const SCEV *OneAlignedUp =
15780-
DividesBy ? GetNextSCEVDividesByDivisor(One, DividesBy) : One;
15769+
GetNextSCEVDividesByDivisor(One, DividesBy);
1578115770
To = SE.getUMaxExpr(FromRewritten, OneAlignedUp);
1578215771
}
1578315772
break;

llvm/test/Transforms/LoopVectorize/single_early_exit.ll

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,15 @@ define i64 @loop_guards_needed_to_prove_deref_multiple(i32 %x, i1 %c, ptr derefe
606606
; CHECK: vector.body:
607607
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[LOOP_HEADER]] ]
608608
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[INDEX]]
609-
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP3]], align 1
609+
; CHECK-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[TMP3]], i32 0
610+
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP11]], align 1
610611
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer
611612
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
612613
; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]]
613614
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP5]])
614615
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[IV_NEXT]]
615616
; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
616-
; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP11:![0-9]+]]
617+
; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_SPLIT:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP14:![0-9]+]]
617618
; CHECK: middle.split:
618619
; CHECK-NEXT: br i1 [[TMP6]], label [[VECTOR_EARLY_EXIT:%.*]], label [[LOOP_LATCH:%.*]]
619620
; CHECK: middle.block:
@@ -635,7 +636,7 @@ define i64 @loop_guards_needed_to_prove_deref_multiple(i32 %x, i1 %c, ptr derefe
635636
; CHECK: loop.latch:
636637
; CHECK-NEXT: [[IV_NEXT1]] = add i64 [[IV1]], 1
637638
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV1]], [[N_EXT]]
638-
; CHECK-NEXT: br i1 [[EC]], label [[EXIT_LOOPEXIT]], label [[LOOP_HEADER1]], !llvm.loop [[LOOP12:![0-9]+]]
639+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT_LOOPEXIT]], label [[LOOP_HEADER1]], !llvm.loop [[LOOP15:![0-9]+]]
639640
; CHECK: exit.loopexit:
640641
; CHECK-NEXT: [[RES_PH:%.*]] = phi i64 [ [[IV1]], [[LOOP_HEADER1]] ], [ 0, [[LOOP_LATCH1]] ], [ 0, [[LOOP_LATCH]] ], [ [[TMP10]], [[VECTOR_EARLY_EXIT]] ]
641642
; CHECK-NEXT: br label [[EXIT]]
@@ -684,4 +685,13 @@ exit:
684685
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
685686
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
686687
; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
688+
; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META1]]}
689+
; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]}
690+
; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]}
691+
; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]}
692+
; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]}
693+
; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]}
694+
; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]}
695+
; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]}
696+
; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META2]], [[META1]]}
687697
;.

0 commit comments

Comments
 (0)