[PATCH] D146596: [SCEV] Infer no-self-wrap via constant ranges
Philip Reames via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 21 19:01:37 PDT 2023
reames created this revision.
reames added reviewers: nikic, efriedma.
Herald added subscribers: StephenFan, javed.absar, bollu, hiraditya, mcrosier.
Herald added a project: All.
reames requested review of this revision.
Herald added a project: LLVM.
Without this, pointer IVs in loops with small constant trip counts couldn't be proven no-self-wrap. This came up in a new LSR transform, but may also benefit other SCEV consumers as well.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D146596
Files:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
llvm/test/Transforms/LoopVersioning/lcssa.ll
Index: llvm/test/Transforms/LoopVersioning/lcssa.ll
===================================================================
--- llvm/test/Transforms/LoopVersioning/lcssa.ll
+++ llvm/test/Transforms/LoopVersioning/lcssa.ll
@@ -56,7 +56,6 @@
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[SCEVGEP]], [[SCEVGEP2]]
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[LS2_21_PROMOTED]], [[SCEVGEP1]]
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
-; CHECK-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, i8* [[LS1_20_PROMOTED]], i64 -1
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %bb1.ph.lver.orig, label %bb1.ph
; CHECK: bb1.ph.lver.orig:
;
Index: llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
===================================================================
--- llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -1633,9 +1633,9 @@
; CHECK-LABEL: 'ptr_induction_ult_1'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_ult_1
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
-; CHECK-NEXT: --> {%a,+,4}<%loop> U: full-set S: full-set Exits: %a LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {%a,+,4}<nw><%loop> U: full-set S: full-set Exits: %a LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
-; CHECK-NEXT: --> {(4 + %a),+,4}<%loop> U: full-set S: full-set Exits: (4 + %a) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_ult_1
; CHECK-NEXT: Loop %loop: backedge-taken count is 0
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0
@@ -1686,18 +1686,17 @@
ret i32 0
}
-; TODO: The pointer induction variable can be implied No Self Wrap.
define void @gep_addrec_nw(ptr %a) {
; CHECK-LABEL: 'gep_addrec_nw'
; CHECK-NEXT: Classifying expressions for: @gep_addrec_nw
; CHECK-NEXT: %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
-; CHECK-NEXT: --> {%a,+,4}<%for.body> U: full-set S: full-set Exits: (1512 + %a) LoopDispositions: { %for.body: Computable }
+; CHECK-NEXT: --> {%a,+,4}<nw><%for.body> U: full-set S: full-set Exits: (1512 + %a) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
; CHECK-NEXT: --> {379,+,-1}<nsw><%for.body> U: [1,380) S: [1,380) Exits: 1 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %lsr.iv.next = add nsw i64 %lsr.iv, -1
; CHECK-NEXT: --> {378,+,-1}<nsw><%for.body> U: [0,379) S: [0,379) Exits: 0 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
-; CHECK-NEXT: --> {(4 + %a),+,4}<%for.body> U: full-set S: full-set Exits: (1516 + %a) LoopDispositions: { %for.body: Computable }
+; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%for.body> U: full-set S: full-set Exits: (1516 + %a) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @gep_addrec_nw
; CHECK-NEXT: Loop %for.body: backedge-taken count is 378
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is 378
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -6769,14 +6769,7 @@
// iteration. The simplest case to consider is a candidate IV which is
// narrower than the trip count (and thus original IV), but this can
// also happen due to non-unit strides on the candidate IVs.
- // TODO: This check should be replaceable with PostInc->hasNoSelfWrap(),
- // but in practice we appear to be missing inference for cases we should
- // be able to catch.
- ConstantRange StepCR = SE.getSignedRange(AddRec->getStepRecurrence(SE));
- ConstantRange BECountCR = SE.getUnsignedRange(BECount);
- unsigned NoOverflowBitWidth = BECountCR.getActiveBits() + StepCR.getMinSignedBits();
- unsigned ARBitWidth = SE.getTypeSizeInBits(AddRec->getType());
- if (NoOverflowBitWidth > ARBitWidth)
+ if (!AddRec->hasNoSelfWrap())
continue;
const SCEVAddRecExpr *PostInc = AddRec->getPostIncExpr(SE);
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4988,6 +4988,18 @@
SCEV::NoWrapFlags Result = SCEV::FlagAnyWrap;
+ if (!AR->hasNoSelfWrap()) {
+ const SCEV *BECount = getBackedgeTakenCount(AR->getLoop(), Exact);
+ if (!isa<SCEVCouldNotCompute>(BECount)) {
+ ConstantRange StepCR = getSignedRange(AR->getStepRecurrence(*this));
+ ConstantRange BECountCR = getUnsignedRange(BECount);
+ unsigned NoOverflowBitWidth =
+ BECountCR.getActiveBits() + StepCR.getMinSignedBits();
+ if (NoOverflowBitWidth <= getTypeSizeInBits(AR->getType()))
+ Result = ScalarEvolution::setFlags(Result, SCEV::FlagNW);
+ }
+ }
+
if (!AR->hasNoSignedWrap()) {
ConstantRange AddRecRange = getSignedRange(AR);
ConstantRange IncRange = getSignedRange(AR->getStepRecurrence(*this));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D146596.507197.patch
Type: text/x-patch
Size: 5521 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230322/7d79d550/attachment-0001.bin>
More information about the llvm-commits
mailing list