diff --git a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll index ff8f32b9c8276..794e9dde44ae4 100644 --- a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll +++ b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll @@ -179,5 +179,89 @@ loop: exit: ret void } + +; // 5*1844674407370955161 == 9223372036854775805 == INT64_MAX - 2, so addrecs don't overflow. +; +; for (i = 0; i < 1844674407370955162; i++) +; for (j = 0; j < 2; j++) { +; offset0 = 5*i - 9223372036854775805*j; +; offset1 = -5*i + 9223372036854775796*j - 1; +; if (offset0 == -5) A[offset0] = 0; +; if (offset1 == -5) A[offset1] = 0; +; } +; +; FIXME: DependenceAnalysis fails to detect dependency between two stores. Also +; GCD MIV misses '='-dependency. +; +; memory accesses | (i,j) == (1844674407370955160,1) +; ------------------------------------|---------------------------------- +; A[ 5*i - 9223372036854775805*j] | A[-5] +; A[-5*i + 9223372036854775796*j - 1] | A[-5] +; +define void @gcdmiv_delta_ovfl2(ptr %A) { +; CHECK-ALL-LABEL: 'gcdmiv_delta_ovfl2' +; 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 0, ptr %gep.1, align 1 +; CHECK-ALL-NEXT: da analyze - none! +; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.1, align 1 --> Dst: store i8 0, ptr %gep.1, align 1 +; CHECK-ALL-NEXT: da analyze - none! +; +; CHECK-GCD-MIV-LABEL: 'gcdmiv_delta_ovfl2' +; 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 - output [* *]! +; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* <>]! +; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.1, align 1 --> Dst: store i8 0, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *]! +; +entry: + br label %loop.i.header + +loop.i.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] + %c.i.0 = phi i64 [ 0, %entry ], [ %c.i.0.next, %loop.i.latch ] + %c.i.1 = phi i64 [ -1, %entry ], [ %c.i.1.next, %loop.i.latch ] + br label %loop.j.header + +loop.j.header: + %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j.latch ] + %offset.0 = phi i64 [ %c.i.0, %loop.i.header ], [ %offset.0.next, %loop.j.latch ] + %offset.1 = phi i64 [ %c.i.1, %loop.i.header ], [ %offset.1.next, %loop.j.latch ] + %cond.0 = icmp eq i64 %offset.0, -5 + br i1 %cond.0, label %if.then.0, label %loop.j.middle + +if.then.0: + %gep.0 = getelementptr i8, ptr %A, i64 %offset.0 + store i8 0, ptr %gep.0 + br label %loop.j.middle + +loop.j.middle: + %cond.1 = icmp eq i64 %offset.1, -5 + br i1 %cond.1, label %if.then.1, label %loop.j.latch + +if.then.1: + %gep.1 = getelementptr i8, ptr %A, i64 %offset.1 + store i8 0, ptr %gep.1 + br label %loop.j.latch + +loop.j.latch: + %j.inc = add i64 %j, 1 + %offset.0.next = add nsw i64 %offset.0, -9223372036854775805 + %offset.1.next = add nsw i64 %offset.1, 9223372036854775796 + %ec.j = icmp eq i64 %j, 2 + br i1 %ec.j, label %loop.i.latch, label %loop.j.header + +loop.i.latch: + %i.inc = add i64 %i, 1 + %c.i.0.next = add nsw i64 %c.i.0, 5 + %c.i.1.next = add nsw i64 %c.i.1, -5 + %ec.i = icmp eq i64 %i.inc, 1844674407370955161 + br i1 %ec.i, label %exit, label %loop.i.header + +exit: + ret void + +} ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; CHECK: {{.*}}