[PATCH] D145905: [LSR]: Terminate folding condition use SymbolicMax.

EverRest via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 13 01:30:59 PDT 2023


MarkGoncharovAl created this revision.
MarkGoncharovAl added a reviewer: eopXD.
Herald added subscribers: s.egerton, simoncook, hiraditya.
Herald added a project: All.
MarkGoncharovAl requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead.
Herald added a project: LLVM.

Term-fold-cond does not work with loop that has upredictable break.
For example, algorithm std::find_if.

It is due to calculating ExactBackedgeTakenCount - the condition is too strong.

If previous basic induction variable has use only inside the loop, then we can replace it and use SymbolicMax to calculate BackedgeTakenCount.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145905

Files:
  llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
  llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-find-if.ll


Index: llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-find-if.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/LoopStrengthReduce/lsr-term-fold-find-if.ll
@@ -0,0 +1,58 @@
+; RUN: opt < %s -passes="loop-reduce" -S -lsr-term-fold -debug-only="loop-reduce" 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32:32-n32:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "riscv32"
+
+; std::ind_if c source code
+; int* __find_if(int *__first, int x, int *__last) {
+;    int __trip_count = (__last - __first);
+;    for (; __trip_count > 0 ; ++__trip_count)
+;    {
+;	     if (*__first == x)
+;	       return __first;
+;	     ++__first;
+;    }
+;    return __first;
+; }
+
+; CHECK: BECount (SCEV): (-1 + (((-1 * (ptrtoint ptr %__first to i32)) + (ptrtoint ptr %__last to i32)) /u 4))<nsw>
+
+; CHECK: for.body:
+; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[INDEC_PTR:%.*]], %if.end ], [ %__first, %for.body.preheader ]
+; CHECK-NEXT: %1 = load i32, ptr %[[LSR_IV1]], align 4
+
+define dso_local ptr @__find_if(ptr noundef %__first, ptr noundef %__last, i32 noundef %x) {
+entry:
+  %sub.ptr.lhs.cast = ptrtoint ptr %__last to i32
+  %sub.ptr.rhs.cast = ptrtoint ptr %__first to i32
+  %sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
+  %cmp6 = icmp sgt i32 %sub.ptr.sub, 0
+  br i1 %cmp6, label %for.body.preheader, label %cleanup
+
+for.body.preheader:                               ; preds = %entry
+  %sub.ptr.div = lshr exact i32 %sub.ptr.sub, 2
+  br label %for.body
+
+; Loop:
+for.body:                                         ; preds = %for.body.preheader, %if.end
+  %__trip_count.08 = phi i32 [ %dec, %if.end ], [ %sub.ptr.div, %for.body.preheader ]
+  %__first.addr.07 = phi ptr [ %incdec.ptr, %if.end ], [ %__first, %for.body.preheader ]
+  %0 = load i32, ptr %__first.addr.07, align 4
+  %cmp1 = icmp eq i32 %0, %x
+  br i1 %cmp1, label %cleanup.loopexit, label %if.end
+
+if.end:                                           ; preds = %for.body
+  %incdec.ptr = getelementptr inbounds i32, ptr %__first.addr.07, i32 1
+  %dec = add nsw i32 %__trip_count.08, -1
+  %cmp = icmp ne i32 %__trip_count.08, 1
+  br i1 %cmp, label %for.body, label %cleanup.loopexit
+
+; Exit blocks
+cleanup.loopexit:                                 ; preds = %for.body, %if.end
+  %__first.addr.0.lcssa.ph = phi ptr [ %incdec.ptr, %if.end ], [ %__first.addr.07, %for.body ]
+  br label %cleanup
+
+cleanup:                                          ; preds = %cleanup.loopexit, %entry
+  %__first.addr.0.lcssa = phi ptr [ %__first, %entry ], [ %__first.addr.0.lcssa.ph, %cleanup.loopexit ]
+  ret ptr %__first.addr.0.lcssa
+}
Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -6694,7 +6694,7 @@
     return std::nullopt;
   }
 
-  if (!SE.hasLoopInvariantBackedgeTakenCount(L)) {
+  if (isa<SCEVCouldNotCompute>(SE.getSymbolicMaxBackedgeTakenCount(L))) {
     LLVM_DEBUG(dbgs() << "Cannot fold on backedge that is loop variant\n");
     return std::nullopt;
   }
@@ -6768,7 +6768,7 @@
   auto getAlternateIVEnd = [&](PHINode &PN) -> const SCEV * {
     // FIXME: This does not properly account for overflow.
     const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
-    const SCEV *BECount = SE.getBackedgeTakenCount(L);
+    const SCEV *BECount = SE.getSymbolicMaxBackedgeTakenCount(L);
     const SCEV *TermValueS = SE.getAddExpr(
         AddRec->getOperand(0),
         SE.getTruncateOrZeroExtend(
@@ -6823,7 +6823,8 @@
 
   LLVM_DEBUG(if (ToFold && ToHelpFold) dbgs()
              << "\nFound loop that can fold terminating condition\n"
-             << "  BECount (SCEV): " << *SE.getBackedgeTakenCount(L) << "\n"
+             << "  BECount (SCEV): " << *SE.getSymbolicMaxBackedgeTakenCount(L)
+             << "\n"
              << "  TermCond: " << *TermCond << "\n"
              << "  BrandInst: " << *BI << "\n"
              << "  ToFold: " << *ToFold << "\n"


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145905.504544.patch
Type: text/x-patch
Size: 4150 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230313/9603720e/attachment.bin>


More information about the llvm-commits mailing list