[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