Skip to content

Commit 56a3e49

Browse files
authored
[ConstraintElim] Support decrementing inductions with step -1. (#68644)
Extend the logic in addInfoForInductions to support decrementing inductions with a step of -1. Fixes #64881.
1 parent 9f12f65 commit 56a3e49

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,26 @@ void State::addInfoForInductions(BasicBlock &BB) {
889889
else
890890
return;
891891

892+
// Handle negative steps.
893+
if (StepOffset.isNegative()) {
894+
// TODO: Extend to allow steps > -1.
895+
if (!(-StepOffset).isOne())
896+
return;
897+
898+
// AR may wrap.
899+
// Add StartValue >= PN conditional on B <= StartValue which guarantees that
900+
// the loop exits before wrapping with a step of -1.
901+
WorkList.push_back(FactOrCheck::getConditionFact(
902+
DTN, CmpInst::ICMP_UGE, StartValue, PN,
903+
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
904+
// Add PN > B conditional on B <= StartValue which guarantees that the loop
905+
// exits when reaching B with a step of -1.
906+
WorkList.push_back(FactOrCheck::getConditionFact(
907+
DTN, CmpInst::ICMP_UGT, PN, B,
908+
ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
909+
return;
910+
}
911+
892912
// Make sure AR either steps by 1 or that the value we compare against is a
893913
// GEP based on the same start value and all offsets are a multiple of the
894914
// step size, to guarantee that the induction will reach the value.

llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-decrement.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ define void @add_rec_decreasing_cond_true_constant(i8 noundef %len) {
1414
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
1515
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
1616
; CHECK: loop.latch:
17-
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
18-
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
17+
; CHECK-NEXT: call void @use(i1 true)
1918
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
2019
; CHECK-NEXT: br label [[LOOP_HEADER]]
2120
; CHECK: exit:
@@ -87,8 +86,7 @@ define void @add_rec_decreasing_cond_true_start_signed_positive(i8 noundef %star
8786
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
8887
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
8988
; CHECK: loop.latch:
90-
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
91-
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
89+
; CHECK-NEXT: call void @use(i1 true)
9290
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
9391
; CHECK-NEXT: br label [[LOOP_HEADER]]
9492
; CHECK: exit:

llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-nested-loops.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ define void @inner_add_rec_decreasing(i32 noundef %len) {
117117
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i32 [[K_0]], 0
118118
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[OUTER_LATCH]], label [[INNER_LATCH]]
119119
; CHECK: inner.latch:
120-
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i32 [[K_0]], [[LEN]]
121-
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
120+
; CHECK-NEXT: call void @use(i1 true)
122121
; CHECK-NEXT: [[K_DEC]] = add i32 [[K_0]], -1
123122
; CHECK-NEXT: br label [[INNER_HEADER]]
124123
; CHECK: outer.latch:

llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ declare void @abort()
270270

271271
define void @monkey(ptr noundef %arr, i32 noundef %len) {
272272
; CHECK-LABEL: define void @monkey
273-
; CHECK-SAME: (ptr nocapture noundef [[ARR:%.*]], i32 noundef [[LEN:%.*]]) local_unnamed_addr {
273+
; CHECK-SAME: (ptr nocapture noundef [[ARR:%.*]], i32 noundef [[LEN:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
274274
; CHECK-NEXT: entry:
275275
; CHECK-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[LEN]], 1
276276
; CHECK-NEXT: br i1 [[CMP8]], label [[FOR_BODY4_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
@@ -284,13 +284,7 @@ define void @monkey(ptr noundef %arr, i32 noundef %len) {
284284
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC]], [[LEN]]
285285
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY4_PREHEADER]], label [[FOR_COND_CLEANUP]]
286286
; CHECK: for.body4:
287-
; CHECK-NEXT: [[K_07:%.*]] = phi i32 [ [[DEC:%.*]], [[AT_EXIT:%.*]] ], [ [[I_09]], [[FOR_BODY4_PREHEADER]] ]
288-
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i32 [[K_07]], [[LEN]]
289-
; CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[AT_EXIT]], label [[IF_THEN_I:%.*]]
290-
; CHECK: if.then.i:
291-
; CHECK-NEXT: tail call void @abort()
292-
; CHECK-NEXT: unreachable
293-
; CHECK: at.exit:
287+
; CHECK-NEXT: [[K_07:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_BODY4]] ], [ [[I_09]], [[FOR_BODY4_PREHEADER]] ]
294288
; CHECK-NEXT: [[IDX_EXT_I:%.*]] = zext i32 [[K_07]] to i64
295289
; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 [[IDX_EXT_I]]
296290
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4

0 commit comments

Comments
 (0)