[llvm] [ConstraintElim] Support decrementing inductions with step -1. (PR #68644)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 9 16:50:40 PDT 2023
https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/68644
Extend the logic in addInfoForInductions to support decrementing inductions with a step of -1.
Fixes #64881.
>From a737357532d0ead20b0bfcbd94718a3486703892 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 23 Aug 2023 22:22:42 +0100
Subject: [PATCH] [ConstraintElim] Support decrementing inductions with step
-1.
Extend the logic in addInfoForInductions to support decrementing
inductions with a step of -1.
Fixes #64881.
---
.../Scalar/ConstraintElimination.cpp | 20 +++++++++++++++++++
.../monotonic-int-phis-decrement.ll | 6 ++----
.../monotonic-int-phis-nested-loops.ll | 3 +--
.../PhaseOrdering/loop-access-checks.ll | 10 ++--------
4 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index e71e7eeb8ef1e18..045827b0345742a 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -889,6 +889,26 @@ void State::addInfoForInductions(BasicBlock &BB) {
else
return;
+ // Handle negative steps.
+ if (StepOffset.isNegative()) {
+ // TODO: Extend to allow steps > -1.
+ if (!(-StepOffset).isOne())
+ return;
+
+ // AR may wrap.h
+ // Add StartValue >= PN conditional on B <= StartValue which guarantees that
+ // the loop exits before wrapping with a step of -1.
+ WorkList.push_back(FactOrCheck::getConditionFact(
+ DTN, CmpInst::ICMP_UGE, StartValue, PN,
+ ConditionTy(CmpInst::ICMP_ULE, B, StartValue)));
+ // 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::getConditionFact(
+ DTN, CmpInst::ICMP_UGT, PN, B,
+ ConditionTy(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.
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-decrement.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-decrement.ll
index 4ebbae54965a43b..155423d33a69a8e 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-decrement.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-decrement.ll
@@ -14,8 +14,7 @@ define void @add_rec_decreasing_cond_true_constant(i8 noundef %len) {
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
-; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
; CHECK-NEXT: br label [[LOOP_HEADER]]
; CHECK: exit:
@@ -87,8 +86,7 @@ define void @add_rec_decreasing_cond_true_start_signed_positive(i8 noundef %star
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
-; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
; CHECK-NEXT: br label [[LOOP_HEADER]]
; CHECK: exit:
diff --git a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-nested-loops.ll b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-nested-loops.ll
index e5d101f7fdea106..11fb48ff007f547 100644
--- a/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-nested-loops.ll
+++ b/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-nested-loops.ll
@@ -117,8 +117,7 @@ define void @inner_add_rec_decreasing(i32 noundef %len) {
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i32 [[K_0]], 0
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[OUTER_LATCH]], label [[INNER_LATCH]]
; CHECK: inner.latch:
-; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i32 [[K_0]], [[LEN]]
-; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[K_DEC]] = add i32 [[K_0]], -1
; CHECK-NEXT: br label [[INNER_HEADER]]
; CHECK: outer.latch:
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index b5895fac28ab0a7..fcf1afce80ec081 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -270,7 +270,7 @@ declare void @abort()
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 @@ define void @monkey(ptr noundef %arr, i32 noundef %len) {
; 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
More information about the llvm-commits
mailing list