[llvm] SCEV: add samesign tests for exit-limit computation (PR #124304)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 24 08:33:01 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
As the tests demonstrate, computeExitLimitFromICmp needs no additional changes to compute exit limits from an icmp with samesign.
---
Full diff: https://github.com/llvm/llvm-project/pull/124304.diff
1 Files Affected:
- (modified) llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll (+235)
``````````diff
diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
index f7a18c77a82c8f..1e15d2d0d6461b 100644
--- a/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exit-count-non-strict.ll
@@ -30,6 +30,35 @@ exit:
ret void
}
+define void @le_from_zero(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_zero'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_zero
+; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
+; CHECK-NEXT: exit count for loop: (1 + (zext i32 %M to i64))<nuw><nsw>
+; CHECK-NEXT: exit count for latch: %N
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4294967295
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
+; CHECK-NEXT: symbolic max exit count for loop: (1 + (zext i32 %M to i64))<nuw><nsw>
+; CHECK-NEXT: symbolic max exit count for latch: %N
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add nuw i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @ule_from_one(i32 %M, i32 %N) {
; CHECK-LABEL: 'ule_from_one'
; CHECK-NEXT: Determining loop execution counts for: @ule_from_one
@@ -59,6 +88,35 @@ exit:
ret void
}
+define void @le_from_one(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_one'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_one
+; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is (%M umin_seq (-1 + %N))
+; CHECK-NEXT: exit count for loop: %M
+; CHECK-NEXT: exit count for latch: (-1 + %N)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%M umin_seq (-1 + %N))
+; CHECK-NEXT: symbolic max exit count for loop: %M
+; CHECK-NEXT: symbolic max exit count for latch: (-1 + %N)
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 1, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add nuw i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @ule_from_unknown(i32 %M, i32 %N, i32 %S) {
; CHECK-LABEL: 'ule_from_unknown'
; CHECK-NEXT: Determining loop execution counts for: @ule_from_unknown
@@ -133,6 +191,51 @@ exit:
ret void
}
+define void @le_from_zero_no_nuw(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_zero_no_nuw'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_zero_no_nuw
+; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: predicated exit count for loop: (1 + (zext i32 %M to i64))<nuw><nsw>
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
+; CHECK-EMPTY:
+; CHECK-NEXT: exit count for latch: %N
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
+; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: predicated symbolic max exit count for loop: (1 + (zext i32 %M to i64))<nuw><nsw>
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
+; CHECK-EMPTY:
+; CHECK-NEXT: symbolic max exit count for latch: %N
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
+; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 4294967295
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
+; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((zext i32 %N to i64) umin (1 + (zext i32 %M to i64))<nuw><nsw>)
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%loop> Added Flags: <nusw>
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @sle_from_int_min(i32 %M, i32 %N) {
; CHECK-LABEL: 'sle_from_int_min'
; CHECK-NEXT: Determining loop execution counts for: @sle_from_int_min
@@ -162,6 +265,35 @@ exit:
ret void
}
+define void @le_from_int_min(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_int_min'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_int_min
+; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is ((-2147483647 + (2147483647 umax %M)) umin_seq (-2147483648 + %N))
+; CHECK-NEXT: exit count for loop: (-2147483647 + (2147483647 umax %M))
+; CHECK-NEXT: exit count for latch: (-2147483648 + %N)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -2147483648
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-2147483647 + (2147483647 umax %M)) umin_seq (-2147483648 + %N))
+; CHECK-NEXT: symbolic max exit count for loop: (-2147483647 + (2147483647 umax %M))
+; CHECK-NEXT: symbolic max exit count for latch: (-2147483648 + %N)
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ u0x80000000, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add nuw nsw i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @sle_from_int_min_plus_one(i32 %M, i32 %N) {
; CHECK-LABEL: 'sle_from_int_min_plus_one'
; CHECK-NEXT: Determining loop execution counts for: @sle_from_int_min_plus_one
@@ -191,6 +323,35 @@ exit:
ret void
}
+define void @le_from_int_min_plus_one(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_int_min_plus_one'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_int_min_plus_one
+; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is ((-2147483648 + (-2147483648 umax %M)) umin_seq (2147483647 + %N))
+; CHECK-NEXT: exit count for loop: (-2147483648 + (-2147483648 umax %M))
+; CHECK-NEXT: exit count for latch: (2147483647 + %N)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 2147483647
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-2147483648 + (-2147483648 umax %M)) umin_seq (2147483647 + %N))
+; CHECK-NEXT: symbolic max exit count for loop: (-2147483648 + (-2147483648 umax %M))
+; CHECK-NEXT: symbolic max exit count for latch: (2147483647 + %N)
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ u0x80000001, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add nuw nsw i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @sle_from_unknown(i32 %M, i32 %N, i32 %S) {
; CHECK-LABEL: 'sle_from_unknown'
; CHECK-NEXT: Determining loop execution counts for: @sle_from_unknown
@@ -220,6 +381,35 @@ exit:
ret void
}
+define void @le_from_unknown(i32 %M, i32 %N, i32 %S) {
+; CHECK-LABEL: 'le_from_unknown'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_unknown
+; CHECK-NEXT: Loop %loop: <multiple exits> backedge-taken count is (((-1 * (zext i32 %S to i64))<nsw> + ((zext i32 %S to i64) umax (1 + (zext i32 %M to i64))<nuw><nsw>)) umin_seq (zext i32 ((-1 * %S) + %N) to i64))
+; CHECK-NEXT: exit count for loop: ((-1 * (zext i32 %S to i64))<nsw> + ((zext i32 %S to i64) umax (1 + (zext i32 %M to i64))<nuw><nsw>))
+; CHECK-NEXT: exit count for latch: ((-1 * %S) + %N)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 4294967295
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (((-1 * (zext i32 %S to i64))<nsw> + ((zext i32 %S to i64) umax (1 + (zext i32 %M to i64))<nuw><nsw>)) umin_seq (zext i32 ((-1 * %S) + %N) to i64))
+; CHECK-NEXT: symbolic max exit count for loop: ((-1 * (zext i32 %S to i64))<nsw> + ((zext i32 %S to i64) umax (1 + (zext i32 %M to i64))<nuw><nsw>))
+; CHECK-NEXT: symbolic max exit count for latch: ((-1 * %S) + %N)
+; CHECK-NEXT: Loop %loop: Trip multiple is 1
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ %S, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add nuw nsw i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
define void @sle_from_int_min_no_nsw(i32 %M, i32 %N) {
; CHECK-LABEL: 'sle_from_int_min_no_nsw'
; CHECK-NEXT: Determining loop execution counts for: @sle_from_int_min_no_nsw
@@ -264,3 +454,48 @@ latch:
exit:
ret void
}
+
+define void @le_from_int_min_no_nuw_nsw(i32 %M, i32 %N) {
+; CHECK-LABEL: 'le_from_int_min_no_nuw_nsw'
+; CHECK-NEXT: Determining loop execution counts for: @le_from_int_min_no_nuw_nsw
+; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: predicated exit count for loop: (-2147483648 + (2147483648 umax (1 + (zext i32 %M to i64))<nuw><nsw>))<nsw>
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nusw>
+; CHECK-EMPTY:
+; CHECK-NEXT: exit count for latch: (-2147483648 + %N)
+; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1
+; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-2147483648 + %N)
+; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: predicated symbolic max exit count for loop: (-2147483648 + (2147483648 umax (1 + (zext i32 %M to i64))<nuw><nsw>))<nsw>
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nusw>
+; CHECK-EMPTY:
+; CHECK-NEXT: symbolic max exit count for latch: (-2147483648 + %N)
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((-2147483648 + (2147483648 umax (1 + (zext i32 %M to i64))<nuw><nsw>))<nsw> umin_seq (zext i32 (-2147483648 + %N) to i64))
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nusw>
+; CHECK-NEXT: Loop %loop: Predicated constant max backedge-taken count is i64 2147483648
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nusw>
+; CHECK-NEXT: Loop %loop: Predicated symbolic max backedge-taken count is ((-2147483648 + (2147483648 umax (1 + (zext i32 %M to i64))<nuw><nsw>))<nsw> umin_seq (zext i32 (-2147483648 + %N) to i64))
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {-2147483648,+,1}<%loop> Added Flags: <nusw>
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ u0x80000000, %entry ], [ %iv.next, %latch ]
+ %cmp1 = icmp samesign ule i32 %iv, %M
+ br i1 %cmp1, label %latch, label %exit
+
+latch:
+ %iv.next = add i32 %iv, 1
+ %exitcond.not = icmp eq i32 %iv, %N
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/124304
More information about the llvm-commits
mailing list