diff --git a/llvm/test/Analysis/DependenceAnalysis/PR148435.ll b/llvm/test/Analysis/DependenceAnalysis/PR148435.ll new file mode 100644 index 0000000000000..54aa9c9399985 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/PR148435.ll @@ -0,0 +1,86 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +define void @_Z1cb(ptr %a) { +; CHECK-LABEL: '_Z1cb' +; CHECK-NEXT: Src: store i8 0, ptr %arrayidx9, align 1 --> Dst: store i8 0, ptr %arrayidx9, align 1 +; CHECK-NEXT: da analyze - output [*]! +; +entry: + br label %for.body + +for.cond.cleanup.loopexit: ; preds = %for.body + ret void + +for.body: ; preds = %for.body, %entry + %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.body ] + %idxprom = and i64 %indvars.iv23, 1 + %arrayidx9 = getelementptr inbounds [0 x [12 x [12 x i8]]], ptr %a, i64 0, i64 %idxprom, i64 0, i64 %indvars.iv23 + store i8 0, ptr %arrayidx9, align 1 + %indvars.iv.next24 = add i64 %indvars.iv23, 1 + %exitcond.not = icmp eq i64 %indvars.iv.next24, 0 + br i1 %exitcond.not, label %for.cond.cleanup.loopexit, label %for.body +} + +@a = external global [0 x [12 x [12 x i8]]], align 1 + +define void @test_siv_no_addrec(i1 %d, i32 %b) { +; CHECK-LABEL: 'test_siv_no_addrec' +; CHECK-NEXT: Src: store i8 0, ptr %arrayidx7, align 1 --> Dst: store i8 0, ptr %arrayidx7, align 1 +; CHECK-NEXT: da analyze - output [* *]! +; +entry: + %conv.val = select i1 %d, i16 1, i16 0 + br label %for.cond + +for.cond: ; preds = %for.inc8, %entry + %e.0 = phi i32 [ %b, %entry ], [ %inc9, %for.inc8 ] + %cmp = icmp ult i32 %e.0, 10 + br i1 %cmp, label %for.cond1, label %for.end10 + +for.cond1: ; preds = %for.inc, %for.cond + %f.0 = phi i16 [ %conv.val, %for.cond ], [ %add, %for.inc ] + %cmp2 = icmp slt i16 %f.0, 10 + br i1 %cmp2, label %for.body4, label %for.inc8 + +for.body4: ; preds = %for.cond1 + %sub = add i32 %e.0, -3 + %idxprom = zext i32 %sub to i64 + %idxprom5 = sext i16 %f.0 to i64 + %idxprom6 = zext i32 %e.0 to i64 + %arrayidx7 = getelementptr inbounds [0 x [12 x [12 x i8]]], ptr @a, i64 0, i64 %idxprom, i64 %idxprom5, i64 %idxprom6 + store i8 0, ptr %arrayidx7, align 1 + br label %for.inc + +for.inc: ; preds = %for.body4 + %add = add i16 %f.0, 2 + br label %for.cond1 + +for.inc8: ; preds = %for.cond1 + %inc9 = add i32 %e.0, 1 + br label %for.cond + +for.end10: ; preds = %for.cond + ret void +} + +define void @f1(ptr %a) { +; CHECK-LABEL: 'f1' +; 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 + +loop: + %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] + %and = and i64 %i, 1 + %idx = getelementptr inbounds [4 x [4 x i8]], ptr %a, i64 0, i64 %and, i64 %and + store i8 0, ptr %idx + %i.next = add i64 %i, 1 + %exitcond.not = icmp slt i64 %i.next, 8 + br i1 %exitcond.not, label %loop, label %exit + +exit: + ret void +} diff --git a/llvm/test/Analysis/DependenceAnalysis/bounds-check.ll b/llvm/test/Analysis/DependenceAnalysis/bounds-check.ll new file mode 100644 index 0000000000000..86086f77d2a47 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/bounds-check.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +; Test case for SmallBitVector bounds checking bug in DependenceAnalysis. +; This test ensures that loop index mapping functions don't cause out-of-bounds +; access to SmallBitVector when loop depths exceed MaxLevels. + +define void @bounds_check_test(ptr %a) { +; CHECK-LABEL: 'bounds_check_test' +; 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 + +loop: + %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] + %and = and i64 %i, 1 ; Creates index 0 or 1 + %idx = getelementptr inbounds [4 x [4 x i8]], ptr %a, i64 0, i64 %and, i64 %i + store i8 0, ptr %idx + %i.next = add i64 %i, 1 + %exitcond.not = icmp slt i64 %i.next, 4 + br i1 %exitcond.not, label %loop, label %exit + +exit: + ret void +} diff --git a/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec-1.ll b/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec-1.ll new file mode 100644 index 0000000000000..00ce2e91809c5 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec-1.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +; Test case for bug #148435 - SIV test assertion failure + +define void @f(ptr %a) { +; CHECK-LABEL: 'f' +; CHECK-NEXT: Src: store i8 42, ptr %idx, align 1 --> Dst: store i8 42, 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 ] + %and.i = and i64 %i, 1 + br label %loop.j + +loop.j: + %j = phi i64 [ 0, %loop.i.header ], [ %j.next, %loop.j ] + %and.j = and i64 %j, 1 + %idx = getelementptr [2 x [2 x i8]], ptr %a, i64 0, i64 %and.i, i64 %and.j + store i8 42, ptr %idx + %j.next = add i64 %j, 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 i64 %i, 1 + %exitcond.i = icmp eq i64 %i.next, 100 + br i1 %exitcond.i, label %exit, label %loop.i.header + +exit: + ret void +} diff --git a/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec.ll b/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec.ll new file mode 100644 index 0000000000000..a1693e9d66575 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/wrapping-addrec.ll @@ -0,0 +1,33 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s + +; Test case for wrapping AddRec detection in DependenceAnalysis. +; This ensures that AddRec expressions that wrap (creating cyclic rather than +; linear patterns) are rejected from SIV analysis and treated conservatively. + +; This test case has a clear dependence pattern that was incorrectly reported as "none!" +; The issue: {false,+,true} in i1 arithmetic creates pattern (0,1,0,1,0,1,...). +; - i=0: a[0][0][0], i=1: a[0][1][1], i=2: a[0][0][0], i=3: a[0][1][1], ... +; - Clear dependencies at distances 2, 4, 6 between iterations accessing same locations. +; - Strong SIV test was missing these due to treating wrapping pattern as linear. + +define void @test_wrapping_i1_addrec(ptr %a) { +; CHECK-LABEL: 'test_wrapping_i1_addrec' +; 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 + +loop: + %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] + %and = and i64 %i, 1 + %idx = getelementptr inbounds [4 x [4 x i8]], ptr %a, i64 0, i64 %and, i64 %and + store i8 0, ptr %idx + %i.next = add i64 %i, 1 + %exitcond.not = icmp slt i64 %i.next, 8 + br i1 %exitcond.not, label %loop, label %exit + +exit: + ret void +}