[llvm] r330256 - [IRCE] Only check for NSW on equality predicates

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 18 06:50:29 PDT 2018


Author: sam_parker
Date: Wed Apr 18 06:50:28 2018
New Revision: 330256

URL: http://llvm.org/viewvc/llvm-project?rev=330256&view=rev
Log:
[IRCE] Only check for NSW on equality predicates

After investigation discussed in D45439, it would seem that the nsw
flag restriction is unnecessary in most cases. So the IsInductionVar
lambda has been removed, the functionality extracted, and now only
require nsw when using eq/ne predicates.

Differential Revision: https://reviews.llvm.org/D45617

Modified:
    llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
    llvm/trunk/test/Transforms/IRCE/stride_more_than_1.ll

Modified: llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp?rev=330256&r1=330255&r2=330256&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp Wed Apr 18 06:50:28 2018
@@ -916,43 +916,28 @@ LoopStructure::parseLoopStructure(Scalar
     return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap;
   };
 
-  // Here we check whether the suggested AddRec is an induction variable that
-  // can be handled (i.e. with known constant step), and if yes, calculate its
-  // step and identify whether it is increasing or decreasing.
-  auto IsInductionVar = [&](const SCEVAddRecExpr *AR, bool &IsIncreasing,
-                            ConstantInt *&StepCI) {
-    if (!AR->isAffine())
-      return false;
-
-    // Currently we only work with induction variables that have been proved to
-    // not wrap.  This restriction can potentially be lifted in the future.
-
-    if (!HasNoSignedWrap(AR))
-      return false;
-
-    if (const SCEVConstant *StepExpr =
-            dyn_cast<SCEVConstant>(AR->getStepRecurrence(SE))) {
-      StepCI = StepExpr->getValue();
-      assert(!StepCI->isZero() && "Zero step?");
-      IsIncreasing = !StepCI->isNegative();
-      return true;
-    }
-
-    return false;
-  };
-
   // `ICI` is interpreted as taking the backedge if the *next* value of the
   // induction variable satisfies some constraint.
 
   const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV);
-  bool IsIncreasing = false;
-  bool IsSignedPredicate = true;
-  ConstantInt *StepCI;
-  if (!IsInductionVar(IndVarBase, IsIncreasing, StepCI)) {
+  if (!IndVarBase->isAffine()) {
     FailureReason = "LHS in icmp not induction variable";
     return None;
   }
+  const SCEV* StepRec = IndVarBase->getStepRecurrence(SE);
+  ConstantInt *StepCI = dyn_cast<SCEVConstant>(StepRec)->getValue();
+  if (!StepCI) {
+    FailureReason = "LHS in icmp not induction variable";
+    return None;
+  }
+  if (ICI->isEquality() && !HasNoSignedWrap(IndVarBase)) {
+    FailureReason = "LHS in icmp needs nsw for equality predicates";
+    return None;
+  }
 
+  assert(!StepCI->isZero() && "Zero step?");
+  bool IsIncreasing = !StepCI->isNegative();
+  bool IsSignedPredicate = ICmpInst::isSigned(Pred);
   const SCEV *StartNext = IndVarBase->getStart();
   const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE));
   const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);

Modified: llvm/trunk/test/Transforms/IRCE/stride_more_than_1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IRCE/stride_more_than_1.ll?rev=330256&r1=330255&r2=330256&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IRCE/stride_more_than_1.ll (original)
+++ llvm/trunk/test/Transforms/IRCE/stride_more_than_1.ll Wed Apr 18 06:50:28 2018
@@ -4,7 +4,7 @@
 ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
 ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
 ; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
-; CHECK-NOT: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
+; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
 ; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
 ; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
 ; CHECK-NOT: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
@@ -206,12 +206,24 @@ exit:
   ret void
 }
 
-; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 6. IRCE is not allowed,
-; because we cannot guarantee that IV + 7 will not exceed MAX_INT.
-; Negative test.
+; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 6. IRCE is allowed
+; because the branch would fail once idx.next == MAX_INT - 1 keeping the
+; access in bounds.
 define void @test_04(i32* %arr, i32* %a_len_ptr) {
-
-; CHECK:      @test_04(
+  ; CHECK:  @test_04(
+  ; CHECK:  loop:
+  ; CHECK:  [[IV:%[^ ]+]] = phi i32
+  ; CHECK:  [[IDX_NEXT:%[^ ]+]] = add i32 [[IV]], 7
+
+  ; CHECK:  main.exit.selector:
+  ; CHECK:  [[PSEUDO_PHI:%[^ ]+]] =  phi i32 [ [[IDX_NEXT]], %in.bounds ]
+  ; CHECK:  [[COND:%[^ ]+]] = icmp slt i32 [[PSEUDO_PHI]], 2147483647
+  ; CHECK:  br i1 [[COND]], label %main.pseudo.exit, label %exit
+
+  ; CHECK: loop.postloop:
+  ; CHECK: [[IDX_POST:%[^ ]+]] = phi i32
+  ; CHECK: [[COND_POST:%[^ ]+]] = icmp slt i32 [[IDX_POST]], %exit.mainloop.at
+  ; CHECK: br i1 [[COND_POST]], label %in.bounds.postloop, label %out.of.bounds.loopexit
 
 entry:
   %len = load i32, i32* %a_len_ptr, !range !2




More information about the llvm-commits mailing list