[llvm] 06c58f1 - [SCEV] Use backedge SCEV of PHI only if its input is loop invariant

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 04:41:11 PDT 2020


Author: Denis Antrushin
Date: 2020-03-31T18:39:24+07:00
New Revision: 06c58f11a99a35da5799de8771cafdc47db69a8a

URL: https://github.com/llvm/llvm-project/commit/06c58f11a99a35da5799de8771cafdc47db69a8a
DIFF: https://github.com/llvm/llvm-project/commit/06c58f11a99a35da5799de8771cafdc47db69a8a.diff

LOG: [SCEV] Use backedge SCEV of PHI only if its input is loop invariant

For the PHI node

      %1 = phi [%A, %entry], [%X, %latch]

it is incorrect to use SCEV of backedge val %X as an exit value
of PHI unless %X is loop invariant.
This is because exit value of %1 is value of %X at one-before-last
iteration of the loop.

Reviewed By: Meinersbur
Differential Revision: https://reviews.llvm.org/D73181

Added: 
    llvm/test/Analysis/ScalarEvolution/pr44605.ll

Modified: 
    llvm/lib/Analysis/ScalarEvolution.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index dffbaf139c4c..b9fd2b422ace 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8285,10 +8285,11 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
           if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) &&
               isKnownPositive(BackedgeTakenCount) &&
               PN->getNumIncomingValues() == 2) {
+
             unsigned InLoopPred = LI->contains(PN->getIncomingBlock(0)) ? 0 : 1;
-            const SCEV *OnBackedge = getSCEV(PN->getIncomingValue(InLoopPred));
-            if (IsAvailableOnEntry(LI, DT, OnBackedge, PN->getParent()))
-              return OnBackedge;
+            Value *BackedgeVal = PN->getIncomingValue(InLoopPred);
+            if (LI->isLoopInvariant(BackedgeVal))
+              return getSCEV(BackedgeVal);
           }
           if (auto *BTCC = dyn_cast<SCEVConstant>(BackedgeTakenCount)) {
             // Okay, we know how many times the containing loop executes.  If

diff  --git a/llvm/test/Analysis/ScalarEvolution/pr44605.ll b/llvm/test/Analysis/ScalarEvolution/pr44605.ll
new file mode 100644
index 000000000000..4d98d8d7f93d
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/pr44605.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Only %local_3_4 is important here.
+;       All other instructions are needed to lure LLVM into executing
+;       specific code to trigger a bug.
+; RUN: opt < %s -indvars -S | FileCheck %s
+define i32 @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[OUTER:%.*]]
+; CHECK:       outer:
+; CHECK-NEXT:    [[LOCAL_6_6:%.*]] = phi i32 [ 10, [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[LATCH:%.*]] ]
+; CHECK-NEXT:    [[LOCAL_4_5:%.*]] = phi i32 [ 56587, [[ENTRY]] ], [ 0, [[LATCH]] ]
+; CHECK-NEXT:    [[LOCAL_3_4:%.*]] = phi i32 [ 2, [[ENTRY]] ], [ [[TMP5]], [[LATCH]] ]
+; CHECK-NEXT:    [[DOTUDIV:%.*]] = udiv i32 [[LOCAL_6_6]], 8361
+; CHECK-NEXT:    br label [[INNER:%.*]]
+; CHECK:       inner:
+; CHECK-NEXT:    [[LOCAL_7_3:%.*]] = phi i32 [ 2, [[OUTER]] ], [ [[TMP3:%.*]], [[INNER]] ]
+; CHECK-NEXT:    [[LOCAL_4_5_PN:%.*]] = phi i32 [ [[LOCAL_4_5]], [[OUTER]] ], [ [[TMP2:%.*]], [[INNER]] ]
+; CHECK-NEXT:    [[LOCAL_3_31:%.*]] = mul i32 [[LOCAL_4_5_PN]], [[DOTUDIV]]
+; CHECK-NEXT:    [[TMP0:%.*]] = mul nuw nsw i32 [[LOCAL_7_3]], [[DOTUDIV]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[LOCAL_3_4]]
+; CHECK-NEXT:    [[TMP2]] = add i32 [[TMP1]], [[LOCAL_3_31]]
+; CHECK-NEXT:    [[TMP3]] = add nuw nsw i32 [[LOCAL_7_3]], 1
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LOCAL_7_3]], 4
+; CHECK-NEXT:    br i1 [[TMP4]], label [[LATCH]], label [[INNER]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi i32 [ [[TMP2]], [[INNER]] ]
+; CHECK-NEXT:    [[TMP5]] = add nuw nsw i32 [[LOCAL_6_6]], 1
+; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i32 [[LOCAL_6_6]], 276
+; CHECK-NEXT:    br i1 [[TMP6]], label [[RETURN:%.*]], label [[OUTER]]
+; CHECK:       return:
+; CHECK-NEXT:    [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ [[DOTLCSSA]], [[LATCH]] ]
+; CHECK-NEXT:    ret i32 [[DOTLCSSA_LCSSA]]
+;
+entry:
+  br label %outer
+
+outer:
+  %local_6_6 = phi i32 [ 10, %entry ], [ %5, %latch ]
+  %local_4_5 = phi i32 [ 56587, %entry ], [ 0, %latch ]
+  %local_3_4 = phi i32 [ 2, %entry ], [ %5, %latch ]
+  %.udiv = udiv i32 %local_6_6, 8361
+  br label %inner
+
+inner:
+  %local_7_3 = phi i32 [ 2, %outer ], [ %3, %inner ]
+  %local_4_5.pn = phi i32 [ %local_4_5, %outer ], [ %2, %inner ]
+  %local_3_31 = mul i32 %local_4_5.pn, %.udiv
+  %0 = mul i32 %local_7_3, %.udiv
+  %1 = sub i32 %0, %local_3_4
+  %2 = add i32 %1, %local_3_31
+  %3 = add nuw nsw i32 %local_7_3, 1
+  %4 = icmp ugt i32 %local_7_3, 4
+  br i1 %4, label %latch, label %inner
+
+latch:
+  %.lcssa = phi i32 [ %2, %inner ]
+  %5 = add nuw nsw i32 %local_6_6, 1
+  %6 = icmp ugt i32 %local_6_6, 276
+  br i1 %6, label %return, label %outer
+
+return:
+  %.lcssa.lcssa = phi i32 [ %.lcssa, %latch ]
+  ret i32 %.lcssa.lcssa
+
+}
+


        


More information about the llvm-commits mailing list