[llvm] [DA] Add tests for nsw doesn't hold on entier iteration (PR #162281)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 7 04:12:40 PST 2025
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/162281
>From 5d7ebe3c1988bc394e5097db9df1ead1b64e4aa0 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Tue, 7 Oct 2025 12:56:14 +0000
Subject: [PATCH] [DA] Add tests for nsw doesn't hold on entier iteration
---
.../monotonicity-loop-guard.ll | 142 ++++++++++++++++++
1 file changed, 142 insertions(+)
create mode 100644 llvm/test/Analysis/DependenceAnalysis/monotonicity-loop-guard.ll
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-loop-guard.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-loop-guard.ll
new file mode 100644
index 0000000000000..290cf3a5336ce
--- /dev/null
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-loop-guard.ll
@@ -0,0 +1,142 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
+; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
+
+; for (i = 0; i < 9223372036854775806; i++)
+; if (i < 2147483640)
+; for (j = 0; j < 2147483640; j++)
+; a[i + j * 4294967296] = 0;
+;
+; FIXME: This is not monotonic. The nsw flag is valid under
+; the condition i < 2147483640, not for all i.
+define void @nsw_under_loop_guard0(ptr %a) {
+; CHECK-LABEL: 'nsw_under_loop_guard0'
+; CHECK-NEXT: Monotonicity check:
+; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,4294967296}<nuw><nsw><%loop.j>
+; CHECK-NEXT: Monotonicity: MultiSignedMonotonic
+; CHECK-EMPTY:
+; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: da analyze - none!
+;
+entry:
+ br label %loop.i.header
+
+loop.i.header:
+ %i = phi i64 [ 0 , %entry ], [ %i.next, %loop.i.latch ]
+ br label %loop.j.pr
+
+loop.j.pr:
+ %guard.j = icmp slt i64 %i, 2147483640
+ br i1 %guard.j, label %loop.j, label %exit
+
+loop.j:
+ %j = phi i64 [ 0, %loop.j.pr ], [ %j.next, %loop.j ]
+ %val = phi i64 [ %i, %loop.j.pr ], [ %val.next, %loop.j ]
+ %j.next = add nsw i64 %j, 1
+ %idx = getelementptr inbounds i8, ptr %a, i64 %val
+ store i8 0, ptr %idx
+ %val.next = add nsw i64 %val, 4294967296
+ %exitcond.j = icmp eq i64 %j.next, 2147483640
+ br i1 %exitcond.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+ %i.next = add nsw i64 %i, 1
+ %exitcond.i = icmp eq i64 %i.next, 9223372036854775806
+ br i1 %exitcond.i, label %exit, label %loop.i.header
+
+exit:
+ ret void
+}
+
+; for (i = 0; i < 100; i++)
+; if (i < 1000)
+; for (j = 0; j < 100; j++)
+; a[i + j] = 0;
+;
+; The loop guard is always true, so the nsw flag is valid for all i.
+define void @nsw_under_loop_guard1(ptr %a) {
+; CHECK-LABEL: 'nsw_under_loop_guard1'
+; CHECK-NEXT: Monotonicity check:
+; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; CHECK-NEXT: Monotonicity: MultiSignedMonotonic
+; CHECK-EMPTY:
+; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: da analyze - output [* *]!
+;
+entry:
+ br label %loop.i.header
+
+loop.i.header:
+ %i = phi i64 [ 0 , %entry ], [ %i.next, %loop.i.latch ]
+ br label %loop.j.pr
+
+loop.j.pr:
+ %guard.j = icmp slt i64 %i, 1000
+ br i1 %guard.j, label %loop.j, label %exit
+
+loop.j:
+ %j = phi i64 [ 0, %loop.j.pr ], [ %j.next, %loop.j ]
+ %val = phi i64 [ %i, %loop.j.pr ], [ %val.next, %loop.j ]
+ %j.next = add nsw i64 %j, 1
+ %idx = getelementptr inbounds i8, ptr %a, i64 %val
+ store i8 0, ptr %idx
+ %val.next = add nsw i64 %val, 1
+ %exitcond.j = icmp eq i64 %j.next, 100
+ br i1 %exitcond.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+ %i.next = add nsw i64 %i, 1
+ %exitcond.i = icmp eq i64 %i.next, 100
+ br i1 %exitcond.i, label %exit, label %loop.i.header
+
+exit:
+ ret void
+}
+
+; for (i = 0; i < n; i++)
+; if (i < m)
+; for (j = 0; j < k; j++)
+; a[i + j] = 0;
+;
+; The nsw flag may valid under the condition i < k.
+define void @nsw_under_loop_guard2(ptr %a, i64 %n, i64 %m, i64 %k) {
+; CHECK-LABEL: 'nsw_under_loop_guard2'
+; CHECK-NEXT: Monotonicity check:
+; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; CHECK-NEXT: Monotonicity: MultiSignedMonotonic
+; CHECK-EMPTY:
+; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: da analyze - output [* *]!
+;
+entry:
+ br label %loop.i.header
+
+loop.i.header:
+ %i = phi i64 [ 0 , %entry ], [ %i.next, %loop.i.latch ]
+ br label %loop.j.pr
+
+loop.j.pr:
+ %guard.j = icmp slt i64 %i, %m
+ br i1 %guard.j, label %loop.j, label %exit
+
+loop.j:
+ %j = phi i64 [ 0, %loop.j.pr ], [ %j.next, %loop.j ]
+ %val = phi i64 [ %i, %loop.j.pr ], [ %val.next, %loop.j ]
+ %j.next = add nsw i64 %j, 1
+ %idx = getelementptr inbounds i8, ptr %a, i64 %val
+ store i8 0, ptr %idx
+ %val.next = add nsw i64 %val, 1
+ %exitcond.j = icmp eq i64 %j.next, %k
+ br i1 %exitcond.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+ %i.next = add nsw i64 %i, 1
+ %exitcond.i = icmp eq i64 %i.next, %n
+ br i1 %exitcond.i, label %exit, label %loop.i.header
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list