[llvm] [DA] Add tests for GCD MIV misses dependency due to overflow (NFC) (PR #169926)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 28 17:32:05 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Ryotaro Kasuga (kasuga-fj)
<details>
<summary>Changes</summary>
Add two test cases where dependencies are missed due to overflows. These will be fixed by #<!-- -->169927 and #<!-- -->169928, respectively.
---
Full diff: https://github.com/llvm/llvm-project/pull/169926.diff
1 Files Affected:
- (modified) llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll (+119)
``````````diff
diff --git a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
index 9169ac323d834..618d14c75faad 100644
--- a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
@@ -56,6 +56,125 @@ loop:
%ec = icmp eq i64 %i.inc, 100
br i1 %ec, label %exit, label %loop
+exit:
+ ret void
+}
+
+; max_i = INT64_MAX/6 // 1537228672809129301
+; for (long long i = 0; i <= max_i; i++) {
+; A[-6*i + INT64_MAX] = 0;
+; if (i)
+; A[3*i - 2] = 1;
+; }
+;
+; FIXME: DependenceAnalysis currently detects no dependency between the two
+; stores, but it does exist. For example,
+;
+; memory access | i == 1 | i == (max_i + 1) / 2 | i == max_i
+; ---------------------|--------|----------------------|-------------------
+; A[-6*i + INT64_MAX] | | A[3*max_i - 2] | A[1]
+; A[3*i - 2] | A[1] | | A[3*max_i - 2]
+;
+;
+define void @gcdmiv_delta_ovfl(ptr %A) {
+; CHECK-ALL-LABEL: 'gcdmiv_delta_ovfl'
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+;
+; CHECK-GCD-MIV-LABEL: 'gcdmiv_delta_ovfl'
+; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
+; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - none!
+; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
+;
+entry:
+ br label %loop.header
+
+loop.header:
+ %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ]
+ %subscript.0 = phi i64 [ 9223372036854775807, %entry ], [ %subscript.0.next, %loop.latch ]
+ %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ]
+ %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0
+ store i8 0, ptr %idx.0
+ %cond.store = icmp ne i64 %i, 0
+ br i1 %cond.store, label %if.store, label %loop.latch
+
+if.store:
+ %idx.1 = getelementptr i8, ptr %A, i64 %subscript.1
+ store i8 1, ptr %idx.1
+ br label %loop.latch
+
+loop.latch:
+ %i.inc = add nuw nsw i64 %i, 1
+ %subscript.0.next = add nsw i64 %subscript.0, -6
+ %subscript.1.next = add nsw i64 %subscript.1, 3
+ %exitcond = icmp sgt i64 %i.inc, 1537228672809129301
+ br i1 %exitcond, label %exit, label %loop.header
+
+exit:
+ ret void
+}
+
+; max_i = INT64_MAX/3 // 3074457345618258602
+; for (i = 0; i < max_i; i++) {
+; A[3*i] = 0;
+; A[-3*i - 3*m - INT64_MAX] = 1;
+; }
+;
+; FIXME: DependenceAnalysis currently detects no dependency between the two
+; stores, but it may exist. For example, consider `m = 1`. Then,
+; `-3*m - INT64_MAX` is `INT64_MAX - 1`. So `-3*i - 3*m - INT64_MAX` is
+; effectively `-3*i + (INT64_MAX - 1)`. Thus, accesses will be as follows:
+;
+; memory access | i == 1 | i == max_i - 1
+; ---------------------------|------------------|------------------
+; A[3*i] | A[3] | A[INT64_MAX - 4]
+; A[-3*i - 3*m - INT64_MAX] | A[INT64_MAX - 4] | A[3]
+;
+
+define void @gcdmiv_const_ovfl(ptr %A, i64 %m) {
+; CHECK-ALL-LABEL: 'gcdmiv_const_ovfl'
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-ALL-NEXT: da analyze - none!
+;
+; CHECK-GCD-MIV-LABEL: 'gcdmiv_const_ovfl'
+; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
+; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - none!
+; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
+; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
+;
+entry:
+ %m.3 = mul nsw i64 -3, %m
+ %const = sub i64 %m.3, 9223372036854775807
+ %guard = icmp ne i64 %const, 0
+ br i1 %guard, label %loop, label %exit
+
+loop:
+ %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ]
+ %offset.0 = phi i64 [ 0, %entry ], [ %offset.0.next, %loop ]
+ %offset.1 = phi i64 [ %const, %entry ], [ %offset.1.next, %loop ]
+ %gep.0 = getelementptr inbounds i8, ptr %A, i64 %offset.0
+ %gep.1 = getelementptr inbounds i8, ptr %A, i64 %offset.1
+ store i8 0, ptr %gep.0
+ store i8 1, ptr %gep.1
+ %i.inc = add nuw nsw i64 %i, 1
+ %offset.0.next = add nsw i64 %offset.0, 3
+ %offset.1.next = add nsw i64 %offset.1, -3
+ %ec = icmp eq i64 %i.inc, 3074457345618258602
+ br i1 %ec, label %exit, label %loop
+
exit:
ret void
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/169926
More information about the llvm-commits
mailing list