Skip to content

Commit e88d3c1

Browse files
buggfgict-qlliliumShadeMrLinWang
committed
[IndVarSimplify] Relax Restrictions on Loop Counter Stride
Co-Authored-By: ict-ql <[email protected]> Co-Authored-By: Chyaka <[email protected]> Co-Authored-By: Lin Wang <[email protected]>
1 parent 61529d9 commit e88d3c1

File tree

6 files changed

+60
-17
lines changed

6 files changed

+60
-17
lines changed

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ static bool hasConcreteDef(Value *V) {
798798

799799
/// Return true if the given phi is a "counter" in L. A counter is an
800800
/// add recurance (of integer or pointer type) with an arbitrary start, and a
801-
/// step of 1. Note that L must have exactly one latch.
801+
/// step of 1/-1. Note that L must have exactly one latch.
802802
static bool isLoopCounter(PHINode* Phi, Loop *L,
803803
ScalarEvolution *SE) {
804804
assert(Phi->getParent() == L->getHeader());
@@ -808,7 +808,13 @@ static bool isLoopCounter(PHINode* Phi, Loop *L,
808808
return false;
809809

810810
const SCEV *S = SE->getSCEV(Phi);
811-
if (!match(S, m_scev_AffineAddRec(m_SCEV(), m_scev_One(), m_SpecificLoop(L))))
811+
const SCEVConstant *Step;
812+
if (!match(S, m_scev_AffineAddRec(m_SCEV(), m_SCEVConstant(Step),
813+
m_SpecificLoop(L))))
814+
return false;
815+
int64_t StepVal = Step->getValue()->getSExtValue();
816+
// Require that the loop counter stride can only be 1 or -1
817+
if (StepVal != 1 && StepVal != -1)
812818
return false;
813819

814820
int LatchIdx = Phi->getBasicBlockIndex(L->getLoopLatch());
@@ -910,7 +916,8 @@ static Value *genLoopLimit(PHINode *IndVar, BasicBlock *ExitingBB,
910916
assert(isLoopCounter(IndVar, L, SE));
911917
assert(ExitCount->getType()->isIntegerTy() && "exit count must be integer");
912918
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
913-
assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride");
919+
const SCEV *StepAbs = SE->getAbsExpr(AR->getStepRecurrence(*SE), true);
920+
assert(StepAbs->isOne() && "only handles unit stride");
914921

915922
// For integer IVs, truncate the IV before computing the limit unless we
916923
// know apriori that the limit must be a constant when evaluated in the

llvm/test/Transforms/IndVarSimplify/X86/pr24356.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ bb:
1414
bb4.preheader: ; preds = %bb, %bb16
1515
; CHECK-LABEL: bb4.preheader:
1616
%b.03 = phi i8 [ 0, %bb ], [ %tmp17, %bb16 ]
17-
; CHECK: %tmp9 = icmp ugt i8 %b.03, 1
18-
; CHECK-NOT: %tmp9 = icmp ugt i8 0, 1
17+
; CHECK: %exitcond = icmp eq i8 %b.03, -1
18+
; CHECK-NOT: %exitcond = icmp ugt i8 0, 1
1919

20-
%tmp9 = icmp ugt i8 %b.03, 1
21-
br i1 %tmp9, label %bb4.preheader.bb18.loopexit.split_crit_edge, label %bb4.preheader.bb4.preheader.split_crit_edge
20+
%exitcond = icmp eq i8 %b.03, -1
21+
br i1 %exitcond, label %bb4.preheader.bb18.loopexit.split_crit_edge, label %bb4.preheader.bb4.preheader.split_crit_edge
2222

2323
bb4.preheader.bb4.preheader.split_crit_edge: ; preds = %bb4.preheader
2424
br label %bb4.preheader.split
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; Test the case where the LoopCounter's stride equals -1.
2+
; RUN: opt -S -passes=indvars < %s | FileCheck %s
3+
4+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
5+
6+
define void @check_step_minus_one(ptr nocapture readonly %0) {
7+
; CHECK-LABEL: define void @check_step_minus_one(ptr readonly captures(none) %0) {
8+
; CHECK: entry:
9+
; CHECK-NEXT: br label [[loop:.*]]
10+
; CHECK: loop:
11+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 31, [[entry:%.*]] ], [ [[PostDec:%.*]], [[loop:%.*]] ]
12+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr %0, i64 [[IV]]
13+
; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4
14+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD]], 1
15+
; CHECK-NEXT: store i32 [[ADD]], ptr [[GEP]], align 4
16+
; CHECK-NEXT: [[PostDec:%.*]] = add nsw i64 [[IV]], -1
17+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[PostDec]], 6
18+
; CHECK-NEXT: br i1 [[CMP]], label [[loop:.*]], label [[end:.*]]
19+
; CHECK: end:
20+
; CHECK-NEXT: ret void
21+
;
22+
entry:
23+
br label %loop
24+
25+
loop:
26+
%1 = phi i64 [ 31, %entry ], [ %6, %loop ]
27+
%3 = getelementptr inbounds i32, ptr %0, i64 %1
28+
%4 = load i32, ptr %3, align 4
29+
%5 = add nsw i32 %4, 1
30+
store i32 %5, ptr %3, align 4
31+
%6 = add nsw i64 %1, -1
32+
%7 = mul nsw i64 %6, %6
33+
%8 = icmp samesign ugt i64 %7, 48
34+
br i1 %8, label %loop, label %end
35+
36+
end:
37+
ret void
38+
}
39+

llvm/test/Transforms/IndVarSimplify/drop-exact.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ define void @drop_exact(ptr %p, ptr %p1) {
1313
; CHECK-NEXT: ret void
1414
; CHECK: bb12:
1515
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ -47436, [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB12]] ]
16-
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP42:%.*]], [[BB12]] ]
1716
; CHECK-NEXT: [[TMP15]] = add nsw i32 [[TMP13]], -1
1817
; CHECK-NEXT: [[TMP16:%.*]] = shl i32 [[TMP15]], 1
1918
; CHECK-NEXT: [[TMP17:%.*]] = sub nsw i32 42831, [[TMP16]]
@@ -23,8 +22,7 @@ define void @drop_exact(ptr %p, ptr %p1) {
2322
; CHECK-NEXT: store i32 [[TMP22]], ptr [[P:%.*]], align 4
2423
; CHECK-NEXT: [[TMP26:%.*]] = zext i32 [[TMP20]] to i64
2524
; CHECK-NEXT: store i64 [[TMP26]], ptr [[P1:%.*]], align 4
26-
; CHECK-NEXT: [[TMP42]] = add nuw nsw i32 [[TMP14]], 1
27-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP42]], 719
25+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP15]], -48155
2826
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB7:%.*]], label [[BB12]]
2927
;
3028
bb:
@@ -60,7 +58,6 @@ define void @dont_drop_exact(ptr %p, ptr %p1) {
6058
; CHECK-NEXT: ret void
6159
; CHECK: bb12:
6260
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ -47436, [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB12]] ]
63-
; CHECK-NEXT: [[TMP14:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP42:%.*]], [[BB12]] ]
6461
; CHECK-NEXT: [[TMP15]] = add nsw i32 [[TMP13]], -1
6562
; CHECK-NEXT: [[TMP16:%.*]] = shl i32 [[TMP15]], 1
6663
; CHECK-NEXT: [[TMP17:%.*]] = sub nsw i32 42831, [[TMP16]]
@@ -70,8 +67,7 @@ define void @dont_drop_exact(ptr %p, ptr %p1) {
7067
; CHECK-NEXT: store i32 [[TMP22]], ptr [[P:%.*]], align 4
7168
; CHECK-NEXT: [[TMP26:%.*]] = zext i32 [[TMP20]] to i64
7269
; CHECK-NEXT: store i64 [[TMP26]], ptr [[P1:%.*]], align 4
73-
; CHECK-NEXT: [[TMP42]] = add nuw nsw i32 [[TMP14]], 1
74-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP42]], 719
70+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP15]], -48155
7571
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB7:%.*]], label [[BB12]]
7672
;
7773
bb:

llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ return:
6868
define i32 @_ZNK4llvm5APInt3ultERKS0_(i32 %tmp2.i1, ptr %tmp65, ptr %tmp73, ptr %tmp82, ptr %tmp90) {
6969
; CHECK-LABEL: @_ZNK4llvm5APInt3ultERKS0_(
7070
; CHECK-NEXT: entry:
71+
; CHECK-NEXT: [[SMIN:%.*]]= call i32 @llvm.smin.i32(i32 %tmp2.i1, i32 -1)
7172
; CHECK-NEXT: br label [[BB18:%.*]]
7273
; CHECK: bb13:
7374
; CHECK-NEXT: [[TMP66:%.*]] = load ptr, ptr [[TMP65:%.*]], align 4
@@ -88,11 +89,11 @@ define i32 @_ZNK4llvm5APInt3ultERKS0_(i32 %tmp2.i1, ptr %tmp65, ptr %tmp73, ptr
8889
; CHECK-NEXT: [[TMP95:%.*]] = icmp ult i64 [[TMP86]], [[TMP94]]
8990
; CHECK-NEXT: br i1 [[TMP95]], label [[BB20_LOOPEXIT]], label [[BB17:%.*]]
9091
; CHECK: bb17:
91-
; CHECK-NEXT: [[TMP97:%.*]] = add nsw i32 [[I]], -1
92+
; CHECK-NEXT: [[TMP97:%.*]] = add i32 [[I]], -1
9293
; CHECK-NEXT: br label [[BB18]]
9394
; CHECK: bb18:
9495
; CHECK-NEXT: [[I]] = phi i32 [ [[TMP2_I1:%.*]], [[ENTRY:%.*]] ], [ [[TMP97]], [[BB17]] ]
95-
; CHECK-NEXT: [[TMP99:%.*]] = icmp sgt i32 [[I]], -1
96+
; CHECK-NEXT: [[TMP99:%.*]] = icmp ne i32 [[I]], [[SMIN:%.*]]
9697
; CHECK-NEXT: br i1 [[TMP99]], label [[BB13:%.*]], label [[BB20_LOOPEXIT]]
9798
; CHECK: bb20.loopexit:
9899
; CHECK-NEXT: [[TMP_0_PH:%.*]] = phi i32 [ 0, [[BB18]] ], [ 1, [[BB15]] ], [ 0, [[BB13]] ]
@@ -917,7 +918,7 @@ define void @func_24(ptr %init.ptr) {
917918
; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
918919
; CHECK: be:
919920
; CHECK-NEXT: call void @side_effect()
920-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp sgt i32 [[IV_DEC]], 4
921+
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ne i32 [[IV_DEC]], 4
921922
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
922923
; CHECK: leave.loopexit:
923924
; CHECK-NEXT: br label [[LEAVE]]

llvm/test/Transforms/IndVarSimplify/lftr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ define i32 @pre_to_post_sub() {
4343
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 1000, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
4444
; CHECK-NEXT: [[I_NEXT]] = sub nsw i32 [[I]], 1
4545
; CHECK-NEXT: store i32 [[I]], ptr @A, align 4
46-
; CHECK-NEXT: [[C:%.*]] = icmp samesign ugt i32 [[I]], 0
46+
; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_NEXT]], -1
4747
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[LOOPEXIT:%.*]]
4848
; CHECK: loopexit:
4949
; CHECK-NEXT: ret i32 0

0 commit comments

Comments
 (0)