[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