https://github.com/kasuga-fj updated 
https://github.com/llvm/llvm-project/pull/162281

>From 5eeaf558673b5e5e129bc2899260e5ec659e04e3 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <[email protected]>
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
+}

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to