[llvm] dec15d9 - [indvars] Use loop guards when canonicalizing exit conditions
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 4 15:24:00 PDT 2021
Author: Philip Reames
Date: 2021-11-04T15:23:34-07:00
New Revision: dec15d9a0a9d91ec17edae3deaa39ac8c01aae77
URL: https://github.com/llvm/llvm-project/commit/dec15d9a0a9d91ec17edae3deaa39ac8c01aae77
DIFF: https://github.com/llvm/llvm-project/commit/dec15d9a0a9d91ec17edae3deaa39ac8c01aae77.diff
LOG: [indvars] Use loop guards when canonicalizing exit conditions
This extends the logic in canonicalizeExitConditions to use loop guards to specialize the SCEV of the loop invariant term before quering it's range.
Added:
Modified:
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index d9858f2f79f8..817e7682cff8 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1456,7 +1456,8 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
const unsigned OuterBitWidth = DL.getTypeSizeInBits(RHS->getType());
auto FullCR = ConstantRange::getFull(InnerBitWidth);
FullCR = FullCR.zeroExtend(OuterBitWidth);
- if (FullCR.contains(SE->getUnsignedRange(SE->getSCEV(RHS)))) {
+ auto RHSCR = SE->getUnsignedRange(SE->applyLoopGuards(SE->getSCEV(RHS), L));
+ if (FullCR.contains(RHSCR)) {
// We have now matched icmp signed-cond zext(X), zext(Y'), and can thus
// replace the signed condition with the unsigned version.
ICmp->setPredicate(ICmp->getUnsignedPredicate());
@@ -1530,7 +1531,8 @@ bool IndVarSimplify::canonicalizeExitCondition(Loop *L) {
const unsigned OuterBitWidth = DL.getTypeSizeInBits(RHS->getType());
auto FullCR = ConstantRange::getFull(InnerBitWidth);
FullCR = FullCR.zeroExtend(OuterBitWidth);
- if (FullCR.contains(SE->getUnsignedRange(SE->getSCEV(RHS)))) {
+ auto RHSCR = SE->getUnsignedRange(SE->applyLoopGuards(SE->getSCEV(RHS), L));
+ if (FullCR.contains(RHSCR)) {
doRotateTransform();
Changed = true;
// Note, we are leaving SCEV in an unfortunately imprecise case here
diff --git a/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll b/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
index 74a85703fe8c..8ae677e1f6df 100644
--- a/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
+++ b/llvm/test/Transforms/IndVarSimplify/finite-exit-comparisons.ll
@@ -989,3 +989,65 @@ for.end: ; preds = %for.body, %entry
ret i16 %iv2
}
+define void @slt_restricted_rhs(i16 %n.raw) mustprogress {
+; CHECK-LABEL: @slt_restricted_rhs(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[N:%.*]] = and i16 [[N_RAW:%.*]], 255
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 [[N]] to i8
+; CHECK-NEXT: br label [[FOR_BODY:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ %n = and i16 %n.raw, 255
+ br label %for.body
+
+for.body: ; preds = %entry, %for.body
+ %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
+ %iv.next = add i8 %iv, 1
+ %zext = zext i8 %iv.next to i16
+ %cmp = icmp slt i16 %zext, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+
+define void @slt_guarded_rhs(i16 %n) mustprogress {
+; CHECK-LABEL: @slt_guarded_rhs(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IN_RANGE:%.*]] = icmp ult i16 [[N:%.*]], 256
+; CHECK-NEXT: br i1 [[IN_RANGE]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
+; CHECK: for.body.preheader:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i16 [[N]] to i8
+; CHECK-NEXT: br label [[FOR_BODY:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[IV_NEXT]], [[TMP0]]
+; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
+; CHECK: for.end.loopexit:
+; CHECK-NEXT: br label [[FOR_END]]
+; CHECK: for.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ %in_range = icmp ult i16 %n, 256
+ br i1 %in_range, label %for.body, label %for.end
+
+for.body: ; preds = %entry, %for.body
+ %iv = phi i8 [ %iv.next, %for.body ], [ 0, %entry ]
+ %iv.next = add i8 %iv, 1
+ %zext = zext i8 %iv.next to i16
+ %cmp = icmp slt i16 %zext, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+
More information about the llvm-commits
mailing list