[PATCH] D104111: [LoopDeletion] Support selects when symbolically evaluating 1st iteration
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 11 04:59:06 PDT 2021
mkazantsev created this revision.
mkazantsev added reviewers: nikic, lebedev.ri, reames.
Herald added a subscriber: hiraditya.
mkazantsev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Adds support for selects for which we know value on the 1st iteration.
https://reviews.llvm.org/D104111
Files:
llvm/lib/Transforms/Scalar/LoopDeletion.cpp
llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
Index: llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
===================================================================
--- llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
+++ llvm/test/Transforms/LoopDeletion/eval_first_iteration.ll
@@ -781,25 +781,26 @@
unreachable
}
-; TODO: We can break the backedge here.
define i32 @test_select_const(i32 %x) {
; CHECK-LABEL: @test_select_const(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[SUB:%.*]] = sub i32 4, [[SUM]]
; CHECK-NEXT: [[IS_POSITIVE:%.*]] = icmp sgt i32 [[SUB]], 0
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[IS_POSITIVE]], i32 [[SUB]], i32 [[X:%.*]]
; CHECK-NEXT: [[SEL_COND:%.*]] = icmp sgt i32 [[SEL]], 0
-; CHECK-NEXT: br i1 [[SEL_COND]], label [[BACKEDGE]], label [[IF_FALSE:%.*]]
+; CHECK-NEXT: br i1 [[SEL_COND]], label [[BACKEDGE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.false:
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[MERGE_PHI:%.*]] = phi i32 [ 0, [[IF_FALSE]] ], [ [[SUB]], [[LOOP]] ]
-; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[MERGE_PHI]]
+; CHECK-NEXT: [[SUM_NEXT:%.*]] = add i32 [[SUM]], [[MERGE_PHI]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[SUM_NEXT]], 4
-; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[DONE:%.*]]
+; CHECK-NEXT: br i1 [[LOOP_COND]], label [[BACKEDGE_LOOP_CRIT_EDGE:%.*]], label [[DONE:%.*]]
+; CHECK: backedge.loop_crit_edge:
+; CHECK-NEXT: unreachable
; CHECK: done:
; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[BACKEDGE]] ]
; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]
Index: llvm/lib/Transforms/Scalar/LoopDeletion.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -176,8 +176,10 @@
const SCEV *S = nullptr;
// TODO: Once ScalarEvolution supports getValueOnNthIteration for anything
// else but AddRecs, it's a good use case for it. So far, just consider some
- // simple cases, like arithmetic operations.
+ // simple cases, like arithmetic operations and selects.
+ ICmpInst::Predicate Pred;
Value *LHS, *RHS;
+ Value *IfTrue, *IfFalse;
using namespace PatternMatch;
if (match(V, m_Add(m_Value(LHS), m_Value(RHS)))) {
const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
@@ -191,6 +193,17 @@
const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
S = SE.getMulExpr(LHSS, RHSS);
+ } else if (match(V, m_Select(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
+ m_Value(IfTrue), m_Value(IfFalse)))) {
+ const SCEV *LHSS = getSCEVOnFirstIteration(LHS, L, SE, FirstIterSCEV);
+ const SCEV *RHSS = getSCEVOnFirstIteration(RHS, L, SE, FirstIterSCEV);
+ if (SE.isKnownPredicate(Pred, LHSS, RHSS))
+ S = getSCEVOnFirstIteration(IfTrue, L, SE, FirstIterSCEV);
+ else if (SE.isKnownPredicate(ICmpInst::getInversePredicate(Pred), LHSS,
+ RHSS))
+ S = getSCEVOnFirstIteration(IfFalse, L, SE, FirstIterSCEV);
+ else
+ S = SE.getSCEV(V);
} else
S = SE.getSCEV(V);
assert(S && "Case not handled?");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104111.351412.patch
Type: text/x-patch
Size: 3545 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210611/619fe47a/attachment-0001.bin>
More information about the llvm-commits
mailing list