[PATCH] D158777: [ConstraintElim] Support decrementing inductions with step -1.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 24 14:00:16 PDT 2023
fhahn created this revision.
fhahn added reviewers: zjaffal, nikic, rapidsna, antoniofrighetto.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
fhahn requested review of this revision.
Herald added a project: LLVM.
Extend the logic in addInfoForInductions to support decrementing
inductions with a step of -1.
NOTE: I still need to add small tests for the patch.
Depends on D152730 <https://reviews.llvm.org/D152730>.
Fixes #64881.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D158777
Files:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
Index: llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
===================================================================
--- llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -270,7 +270,7 @@
define void @monkey(ptr noundef %arr, i32 noundef %len) {
; CHECK-LABEL: define void @monkey
-; CHECK-SAME: (ptr nocapture noundef [[ARR:%.*]], i32 noundef [[LEN:%.*]]) local_unnamed_addr {
+; CHECK-SAME: (ptr nocapture noundef [[ARR:%.*]], i32 noundef [[LEN:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[LEN]], 1
; CHECK-NEXT: br i1 [[CMP8]], label [[FOR_BODY4_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
@@ -284,13 +284,7 @@
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC]], [[LEN]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY4_PREHEADER]], label [[FOR_COND_CLEANUP]]
; CHECK: for.body4:
-; CHECK-NEXT: [[K_07:%.*]] = phi i32 [ [[DEC:%.*]], [[AT_EXIT:%.*]] ], [ [[I_09]], [[FOR_BODY4_PREHEADER]] ]
-; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i32 [[K_07]], [[LEN]]
-; CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[AT_EXIT]], label [[IF_THEN_I:%.*]]
-; CHECK: if.then.i:
-; CHECK-NEXT: tail call void @abort()
-; CHECK-NEXT: unreachable
-; CHECK: at.exit:
+; CHECK-NEXT: [[K_07:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_BODY4]] ], [ [[I_09]], [[FOR_BODY4_PREHEADER]] ]
; CHECK-NEXT: [[IDX_EXT_I:%.*]] = zext i32 [[K_07]] to i64
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 [[IDX_EXT_I]]
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4
Index: llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -830,7 +830,8 @@
return;
auto *AR = dyn_cast_or_null<SCEVAddRecExpr>(SE.getSCEV(PN));
- if (!AR)
+ BasicBlock *LoopPred = L->getLoopPredecessor();
+ if (!AR || !LoopPred)
return;
const SCEV *StartSCEV = AR->getStart();
@@ -839,9 +840,11 @@
StartValue = C->getValue();
else if (auto *U = dyn_cast<SCEVUnknown>(StartSCEV))
StartValue = U->getValue();
-
- if (!StartValue)
- return;
+ else {
+ StartValue = PN->getIncomingValueForBlock(LoopPred);
+ if (SE.getSCEV(StartValue) != AR->getStart())
+ return;
+ }
Type *StepTy = AR->getType();
const DataLayout &DL = BB.getModule()->getDataLayout();
@@ -853,6 +856,25 @@
else
return;
+ // Handle negative steps.
+ if (StepOffset.isNegative()) {
+ // TODO: Extend to allow steps > -1.
+ if (!(-StepOffset).isOne())
+ return;
+
+ // AR may wrap. Add StartValue >= PN conditional on B <= StartValue which
+ // guarantees that the loop exits before wrapping with a step of -1.
+ auto *DTN = DT.getNode(Succ);
+ WorkList.push_back(FactOrCheck::getFact(DTN, CmpInst::ICMP_UGE, StartValue,
+ PN, CmpInst::ICMP_ULE, B,
+ StartValue));
+ // AR may wrap. Add PN > B conditional on B <= StartValue which guarantees
+ // that the loop exits when reaching B with a step of -1.
+ WorkList.push_back(FactOrCheck::getFact(DTN, CmpInst::ICMP_UGT, PN, B,
+ CmpInst::ICMP_ULE, B, StartValue));
+ return;
+ }
+
// Make sure AR either steps by 1 or that the value we compare against is a
// GEP based on the same start value and all offsets are a multiple of the
// step size, to guarantee that the induction will reach the value.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D158777.553252.patch
Type: text/x-patch
Size: 3737 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230824/910436c6/attachment.bin>
More information about the llvm-commits
mailing list