[llvm] SCEV, IndVarSimplify: add samesign test from a regression (PR #125539)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 3 09:28:39 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
While attempting to teach ScalarEvolution about samesign in another effort, a complicated testcase with nested loops, and zero-extends of the induction-variable regresses, but only when the target datalayout is present. The regression was originally reported on IndVarSimplify, but an improvement of symbolic BTC was also observed on SCEV. Check in the test into both IndVarSimplify and SCEV, to ease investigation and further development.
---
Full diff: https://github.com/llvm/llvm-project/pull/125539.diff
2 Files Affected:
- (added) llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll (+44)
- (added) llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll (+62)
``````````diff
diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll
new file mode 100644
index 00000000000000..e0bb6acaff7954
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll
@@ -0,0 +1,44 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -disable-output "-passes=print<scalar-evolution>" \
+; RUN: -scalar-evolution-classify-expressions=0 < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: 'exit_count_samesign'
+; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign
+; CHECK-NEXT: Loop %inner.loop: backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
+; CHECK-NEXT: Loop %inner.loop: constant max backedge-taken count is i32 2147483646
+; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
+; CHECK-NEXT: Loop %inner.loop: Trip multiple is 1
+; CHECK-NEXT: Loop %outer.loop: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %outer.loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %outer.loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer
+ store double poison, ptr %gep.outer
+ %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner
+ store double poison, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll b/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll
new file mode 100644
index 00000000000000..94dd4d18324e1e
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=indvars -S | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+define i32 @iv_zext_samesign(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_samesign(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store double poison, ptr [[GEP_INNER]], align 8
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer
+ store double poison, ptr %gep.outer
+ %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner
+ store double poison, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/125539
More information about the llvm-commits
mailing list