aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/BasicAA
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/BasicAA')
-rw-r--r--test/Analysis/BasicAA/2007-11-05-SizeCrash.ll2
-rw-r--r--test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll2
-rw-r--r--test/Analysis/BasicAA/bug.23540.ll17
-rw-r--r--test/Analysis/BasicAA/bug.23626.ll31
-rw-r--r--test/Analysis/BasicAA/cs-cs.ll41
-rw-r--r--test/Analysis/BasicAA/full-store-partial-alias.ll4
-rw-r--r--test/Analysis/BasicAA/intrinsics.ll27
-rw-r--r--test/Analysis/BasicAA/modref.ll37
-rw-r--r--test/Analysis/BasicAA/noalias-bugs.ll2
-rw-r--r--test/Analysis/BasicAA/phi-aa.ll1
-rw-r--r--test/Analysis/BasicAA/phi-loop.ll75
-rw-r--r--test/Analysis/BasicAA/q.bad.ll180
-rw-r--r--test/Analysis/BasicAA/sequential-gep.ll54
-rw-r--r--test/Analysis/BasicAA/zext.ll231
14 files changed, 668 insertions, 36 deletions
diff --git a/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll b/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll
index 069bd0bcfd8f..b59ee42dec3a 100644
--- a/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll
+++ b/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll
@@ -9,7 +9,7 @@ target triple = "x86_64-unknown-linux-gnu"
%struct.usb_hcd = type { %struct.usb_bus, i64, [0 x i64] }
@uhci_pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer
-@__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @uhci_pci_ids
+@__mod_pci_device_table = alias [1 x %struct.pci_device_id], [1 x %struct.pci_device_id]* @uhci_pci_ids
; <[1 x %struct.pci_device_id]*> [#uses=0]
define i32 @uhci_suspend(%struct.usb_hcd* %hcd) {
diff --git a/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll b/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll
index 20be13d153bb..ba9740028180 100644
--- a/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll
+++ b/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll
@@ -9,7 +9,7 @@ target triple = "x86_64-unknown-linux-gnu"
%struct.usb_hcd = type { %struct.usb_bus, [0 x i64] }
@pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer
-@__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @pci_ids ; <[1 x %struct.pci_device_id]*> [#uses=0]
+@__mod_pci_device_table = alias [1 x %struct.pci_device_id], [1 x %struct.pci_device_id]* @pci_ids ; <[1 x %struct.pci_device_id]*> [#uses=0]
define i32 @ehci_pci_setup(%struct.usb_hcd* %hcd) {
entry:
diff --git a/test/Analysis/BasicAA/bug.23540.ll b/test/Analysis/BasicAA/bug.23540.ll
new file mode 100644
index 000000000000..f693bcf73cd6
--- /dev/null
+++ b/test/Analysis/BasicAA/bug.23540.ll
@@ -0,0 +1,17 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@c = external global i32
+
+; CHECK-LABEL: f
+; CHECK: PartialAlias: i32* %arrayidx, i32* %arrayidx6
+define void @f() {
+ %idxprom = zext i32 undef to i64
+ %add4 = add i32 0, 1
+ %idxprom5 = zext i32 %add4 to i64
+ %arrayidx6 = getelementptr inbounds i32, i32* @c, i64 %idxprom5
+ %arrayidx = getelementptr inbounds i32, i32* @c, i64 %idxprom
+ ret void
+}
+
diff --git a/test/Analysis/BasicAA/bug.23626.ll b/test/Analysis/BasicAA/bug.23626.ll
new file mode 100644
index 000000000000..6a1478c65cef
--- /dev/null
+++ b/test/Analysis/BasicAA/bug.23626.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-darwin13.4.0"
+
+; CHECK-LABEL: compute1
+; CHECK: PartialAlias: i32* %arrayidx8, i32* %out
+; CHECK: PartialAlias: i32* %arrayidx11, i32* %out
+; CHECK: PartialAlias: i32* %arrayidx11, i32* %arrayidx8
+; CHECK: PartialAlias: i32* %arrayidx14, i32* %out
+; CHECK: PartialAlias: i32* %arrayidx14, i32* %arrayidx8
+; CHECK: PartialAlias: i32* %arrayidx11, i32* %arrayidx14
+define void @compute1(i32 %num.0.lcssa, i32* %out) {
+ %idxprom = zext i32 %num.0.lcssa to i64
+ %arrayidx8 = getelementptr inbounds i32, i32* %out, i64 %idxprom
+ %add9 = or i32 %num.0.lcssa, 1
+ %idxprom10 = zext i32 %add9 to i64
+ %arrayidx11 = getelementptr inbounds i32, i32* %out, i64 %idxprom10
+ %add12 = or i32 %num.0.lcssa, 2
+ %idxprom13 = zext i32 %add12 to i64
+ %arrayidx14 = getelementptr inbounds i32, i32* %out, i64 %idxprom13
+ ret void
+}
+
+; CHECK-LABEL: compute2
+; CHECK: PartialAlias: i32* %arrayidx11, i32* %out.addr
+define void @compute2(i32 %num, i32* %out.addr) {
+ %add9 = add i32 %num, 1
+ %idxprom10 = zext i32 %add9 to i64
+ %arrayidx11 = getelementptr inbounds i32, i32* %out.addr, i64 %idxprom10
+ ret void
+}
diff --git a/test/Analysis/BasicAA/cs-cs.ll b/test/Analysis/BasicAA/cs-cs.ll
index 78670b61ca1c..dc298f1668be 100644
--- a/test/Analysis/BasicAA/cs-cs.ll
+++ b/test/Analysis/BasicAA/cs-cs.ll
@@ -2,8 +2,8 @@
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "arm-apple-ios"
-declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*, i32) nounwind readonly
-declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind
+declare <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8*, i32) nounwind readonly
+declare void @llvm.arm.neon.vst1.p0i8.v8i16(i8*, <8 x i16>, i32) nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
@@ -13,27 +13,27 @@ declare void @a_readonly_func(i8 *) noinline nounwind readonly
define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
entry:
%q = getelementptr i8, i8* %p, i64 16
- %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
- call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
- %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
+ %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
+ call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+ %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
%c = add <8 x i16> %a, %b
ret <8 x i16> %c
; CHECK-LABEL: Function: test1:
; CHECK: NoAlias: i8* %p, i8* %q
-; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
}
define void @test2(i8* %P, i8* %Q) nounwind ssp {
@@ -233,4 +233,9 @@ define void @test6(i8* %P) nounwind ssp {
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
}
-attributes #0 = { nounwind }
+attributes #0 = { nounwind readonly argmemonly }
+attributes #1 = { nounwind argmemonly }
+attributes #2 = { noinline nounwind readonly }
+attributes #3 = { nounwind ssp }
+attributes #4 = { nounwind }
+
diff --git a/test/Analysis/BasicAA/full-store-partial-alias.ll b/test/Analysis/BasicAA/full-store-partial-alias.ll
index 341f6ba23b3a..20f6f7ec4ad0 100644
--- a/test/Analysis/BasicAA/full-store-partial-alias.ll
+++ b/test/Analysis/BasicAA/full-store-partial-alias.ll
@@ -1,5 +1,5 @@
-; RUN: opt -S -tbaa -basicaa -gvn < %s | FileCheck -check-prefix=BASICAA %s
-; RUN: opt -S -tbaa -gvn < %s | FileCheck %s
+; RUN: opt -S -tbaa -gvn < %s | FileCheck -check-prefix=BASICAA %s
+; RUN: opt -S -tbaa -disable-basicaa -gvn < %s | FileCheck %s
; rdar://8875631, rdar://8875069
; BasicAA should notice that the store stores to the entire %u object,
diff --git a/test/Analysis/BasicAA/intrinsics.ll b/test/Analysis/BasicAA/intrinsics.ll
index 8c05587ce233..526a039ef7ac 100644
--- a/test/Analysis/BasicAA/intrinsics.ll
+++ b/test/Analysis/BasicAA/intrinsics.ll
@@ -7,14 +7,14 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-
; CHECK: define <8 x i16> @test0(i8* noalias %p, i8* noalias %q, <8 x i16> %y) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) [[ATTR:#[0-9]+]]
-; CHECK-NEXT: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) [[ATTR:#[0-9]+]]
+; CHECK-NEXT: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK-NEXT: %c = add <8 x i16> %a, %a
define <8 x i16> @test0(i8* noalias %p, i8* noalias %q, <8 x i16> %y) {
entry:
- %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
- call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
- %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
+ %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
+ call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+ %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
%c = add <8 x i16> %a, %b
ret <8 x i16> %c
}
@@ -22,21 +22,22 @@ entry:
; CHECK: define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %q = getelementptr i8, i8* %p, i64 16
-; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) [[ATTR]]
-; CHECK-NEXT: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK-NEXT: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) [[ATTR]]
+; CHECK-NEXT: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK-NEXT: %c = add <8 x i16> %a, %a
define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
entry:
%q = getelementptr i8, i8* %p, i64 16
- %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
- call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
- %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
+ %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
+ call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+ %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) nounwind
%c = add <8 x i16> %a, %b
ret <8 x i16> %c
}
-declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*, i32) nounwind readonly
-declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind
+declare <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8*, i32) nounwind readonly
+declare void @llvm.arm.neon.vst1.p0i8.v8i16(i8*, <8 x i16>, i32) nounwind
-; CHECK: attributes #0 = { nounwind readonly }
+; CHECK: attributes #0 = { argmemonly nounwind readonly }
+; CHECK: attributes #1 = { argmemonly nounwind }
; CHECK: attributes [[ATTR]] = { nounwind }
diff --git a/test/Analysis/BasicAA/modref.ll b/test/Analysis/BasicAA/modref.ll
index 3084f809c370..e42793936c3d 100644
--- a/test/Analysis/BasicAA/modref.ll
+++ b/test/Analysis/BasicAA/modref.ll
@@ -190,6 +190,43 @@ define i32 @test10(i32* %P, i32* %P2) {
; CHECK: ret i32 %Diff
}
+; CHECK-LABEL: @test11(
+define i32 @test11(i32* %P, i32* %P2) {
+ %V1 = load i32, i32* %P
+ call i32 @func_argmemonly(i32* readonly %P2)
+ %V2 = load i32, i32* %P
+ %Diff = sub i32 %V1, %V2
+ ret i32 %Diff
+ ; CHECK-NOT: load
+ ; CHECK: ret i32 0
+}
+
+declare i32 @func_argmemonly_two_args(i32* %P, i32* %P2) argmemonly
+
+; CHECK-LABEL: @test12(
+define i32 @test12(i32* %P, i32* %P2, i32* %P3) {
+ %V1 = load i32, i32* %P
+ call i32 @func_argmemonly_two_args(i32* readonly %P2, i32* %P3)
+ %V2 = load i32, i32* %P
+ %Diff = sub i32 %V1, %V2
+ ret i32 %Diff
+ ; CHECK: load
+ ; CHECK: load
+ ; CHECK: sub
+ ; CHECK: ret i32 %Diff
+}
+
+; CHECK-LABEL: @test13(
+define i32 @test13(i32* %P, i32* %P2) {
+ %V1 = load i32, i32* %P
+ call i32 @func_argmemonly(i32* readnone %P2)
+ %V2 = load i32, i32* %P
+ %Diff = sub i32 %V1, %V2
+ ret i32 %Diff
+ ; CHECK-NOT: load
+ ; CHECK: ret i32 0
+}
+
declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i32, i1) nounwind
diff --git a/test/Analysis/BasicAA/noalias-bugs.ll b/test/Analysis/BasicAA/noalias-bugs.ll
index acb230c45de4..71b3c443f542 100644
--- a/test/Analysis/BasicAA/noalias-bugs.ll
+++ b/test/Analysis/BasicAA/noalias-bugs.ll
@@ -24,7 +24,7 @@ define i64 @testcase(%nested * noalias %p1, %nested * noalias %p2,
; CHECK: store i64 2
; CHECK: load
-; CHECK; store i64 1
+; CHECK: store i64 1
store i64 2, i64* %ptr.64, align 8
%r = load i64, i64* %either_ptr.64, align 8
diff --git a/test/Analysis/BasicAA/phi-aa.ll b/test/Analysis/BasicAA/phi-aa.ll
index a72778277bb2..3944e9e43566 100644
--- a/test/Analysis/BasicAA/phi-aa.ll
+++ b/test/Analysis/BasicAA/phi-aa.ll
@@ -39,6 +39,7 @@ return:
; CHECK-LABEL: pr18068
; CHECK: MayAlias: i32* %0, i32* %arrayidx5
+; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5
define i32 @pr18068(i32* %jj7, i32* %j) {
entry:
diff --git a/test/Analysis/BasicAA/phi-loop.ll b/test/Analysis/BasicAA/phi-loop.ll
new file mode 100644
index 000000000000..6337bfbc1cfb
--- /dev/null
+++ b/test/Analysis/BasicAA/phi-loop.ll
@@ -0,0 +1,75 @@
+; RUN: opt < %s -basicaa -basicaa-recphi=1 -gvn -S | FileCheck %s
+;
+; Check that section->word_ofs doesn't get reloaded in every iteration of the
+; for loop.
+;
+; Code:
+;
+; typedef struct {
+; unsigned num_words;
+; unsigned word_ofs;
+; const unsigned *data;
+; } section_t;
+;
+;
+; void test2(const section_t * restrict section, unsigned * restrict dst) {;
+; while (section->data != NULL) {
+; const unsigned *src = section->data;
+; for (unsigned i=0; i < section->num_words; ++i) {
+; dst[section->word_ofs + i] = src[i];
+; }
+;
+; ++section;
+; }
+; }
+;
+
+; CHECK-LABEL: for.body:
+; CHECK-NOT: load i32, i32* %word_ofs
+
+%struct.section_t = type { i32, i32, i32* }
+
+define void @test2(%struct.section_t* noalias nocapture readonly %section, i32* noalias nocapture %dst) {
+entry:
+ %data13 = getelementptr inbounds %struct.section_t, %struct.section_t* %section, i32 0, i32 2
+ %0 = load i32*, i32** %data13, align 4
+ %cmp14 = icmp eq i32* %0, null
+ br i1 %cmp14, label %while.end, label %for.cond.preheader
+
+for.cond.preheader: ; preds = %entry, %for.end
+ %1 = phi i32* [ %6, %for.end ], [ %0, %entry ]
+ %section.addr.015 = phi %struct.section_t* [ %incdec.ptr, %for.end ], [ %section, %entry ]
+ %num_words = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 0, i32 0
+ %2 = load i32, i32* %num_words, align 4
+ %cmp211 = icmp eq i32 %2, 0
+ br i1 %cmp211, label %for.end, label %for.body.lr.ph
+
+for.body.lr.ph: ; preds = %for.cond.preheader
+ %word_ofs = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 0, i32 1
+ br label %for.body
+
+for.body: ; preds = %for.body.lr.ph, %for.body
+ %arrayidx.phi = phi i32* [ %1, %for.body.lr.ph ], [ %arrayidx.inc, %for.body ]
+ %i.012 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+ %3 = load i32, i32* %arrayidx.phi, align 4
+ %4 = load i32, i32* %word_ofs, align 4
+ %add = add i32 %4, %i.012
+ %arrayidx3 = getelementptr inbounds i32, i32* %dst, i32 %add
+ store i32 %3, i32* %arrayidx3, align 4
+ %inc = add i32 %i.012, 1
+ %5 = load i32, i32* %num_words, align 4
+ %cmp2 = icmp ult i32 %inc, %5
+ %arrayidx.inc = getelementptr i32, i32* %arrayidx.phi, i32 1
+ br i1 %cmp2, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %for.cond.preheader
+ %incdec.ptr = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 1
+ %data = getelementptr inbounds %struct.section_t, %struct.section_t* %section.addr.015, i32 1, i32 2
+ %6 = load i32*, i32** %data, align 4
+ %cmp = icmp eq i32* %6, null
+ br i1 %cmp, label %while.end, label %for.cond.preheader
+
+while.end: ; preds = %for.end, %entry
+ ret void
+}
+
diff --git a/test/Analysis/BasicAA/q.bad.ll b/test/Analysis/BasicAA/q.bad.ll
new file mode 100644
index 000000000000..f2de6a76c5e0
--- /dev/null
+++ b/test/Analysis/BasicAA/q.bad.ll
@@ -0,0 +1,180 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv7--linux-gnueabi"
+
+; CHECK-LABEL: test_zext_sext_amounts255
+; CHECK: NoAlias: i8* %a, i8* %b
+define void @test_zext_sext_amounts255(i8* %mem) {
+ %sext.1 = sext i8 255 to i16
+ %sext.zext.1 = zext i16 %sext.1 to i64
+ %sext.2 = sext i8 255 to i32
+ %sext.zext.2 = zext i32 %sext.2 to i64
+ %a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
+ %b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
+ ret void
+}
+
+; CHECK-LABEL: test_zext_sext_amounts
+; CHECK: PartialAlias: i8* %a, i8* %b
+; %a and %b only PartialAlias as, although they're both zext(sext(%num)) they'll extend the sign by a different
+; number of bits before zext-ing the remainder.
+define void @test_zext_sext_amounts(i8* %mem, i8 %num) {
+ %sext.1 = sext i8 %num to i16
+ %sext.zext.1 = zext i16 %sext.1 to i64
+ %sext.2 = sext i8 %num to i32
+ %sext.zext.2 = zext i32 %sext.2 to i64
+ %a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
+ %b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
+ ret void
+}
+
+; CHECK-LABEL: based_on_pr18068
+; CHECK: NoAlias: i8* %a, i8* %b
+; CHECK: NoAlias: i8* %a, i8* %c
+define void @based_on_pr18068(i32 %loaded, i8* %mem) {
+ %loaded.64 = zext i32 %loaded to i64
+ %add1 = add i32 %loaded, -1 ; unsigned wraps unless %loaded == 0
+ %add1.64 = zext i32 %add1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
+ %sub1 = sub i32 %loaded, 1 ; unsigned wraps iff %loaded == 0
+ %sub1.64 = zext i32 %sub1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
+ %a = getelementptr inbounds i8, i8* %mem, i64 %loaded.64
+ %b = getelementptr inbounds i8, i8* %mem, i64 %add1.64
+ %c = getelementptr inbounds i8, i8* %mem, i64 %sub1.64
+ ret void
+}
+
+; CHECK-LABEL: test_path_dependence
+; CHECK: PartialAlias: i8* %a, i8* %b
+; CHECK: MustAlias: i8* %a, i8* %c
+; CHECK: PartialAlias: i8* %a, i8* %d
+define void @test_path_dependence(i32 %p, i8* %mem) {
+ %p.minus1 = add i32 %p, -1 ; this will always unsigned-wrap, unless %p == 0
+ %p.minus1.64 = zext i32 %p.minus1 to i64
+ %p.64.again = add i64 %p.minus1.64, 1 ; either %p (if we wrapped) or 4294967296 (if we didn't)
+
+ %p.nsw.nuw.minus1 = sub nsw nuw i32 %p, 1 ; as nuw we know %p >= 1, and as nsw %p <= 2147483647
+ %p.nsw.nuw.minus1.64 = zext i32 %p.nsw.nuw.minus1 to i64
+ %p.nsw.nuw.64.again = add nsw nuw i64 %p.nsw.nuw.minus1.64, 1 ; ...so always exactly %p
+
+ %p.nsw.minus1 = sub nsw i32 %p, 1 ; only nsw, so can only guarantee %p != 0x10000000
+ %p.nsw.minus1.64 = zext i32 %p.nsw.minus1 to i64 ; when %p > 0x10000000 (ie <= 0 as a signed number) then the zext will make this a huge positive number
+ %p.nsw.64.again = add nsw i64 %p.nsw.minus1.64, 1 ; ...and so this is very much != %p
+
+ %p.64 = zext i32 %p to i64
+ %a = getelementptr inbounds i8, i8* %mem, i64 %p.64
+ %b = getelementptr inbounds i8, i8* %mem, i64 %p.64.again
+ %c = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.nuw.64.again
+ %d = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.64.again
+ ret void
+}
+
+; CHECK-LABEL: test_zext_sext_255
+; CHECK: NoAlias: i8* %a, i8* %b
+define void @test_zext_sext_255(i8* %mem) {
+ %zext.255 = zext i8 255 to i16 ; 0x00FF
+ %sext.255 = sext i8 255 to i16 ; 0xFFFF
+ %zext.sext.255 = zext i16 %sext.255 to i32 ; 0x0000FFFF
+ %sext.zext.255 = sext i16 %zext.255 to i32 ; 0x000000FF
+ %zext.zext.sext.255 = zext i32 %zext.sext.255 to i64
+ %zext.sext.zext.255 = zext i32 %sext.zext.255 to i64
+ %a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.255
+ %b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.255
+ ret void
+}
+
+; CHECK-LABEL: test_zext_sext_num
+; CHECK: PartialAlias: i8* %a, i8* %b
+; %a and %b NoAlias if %num == 255 (see @test_zext_sext_255), but %a and %b NoAlias for other values of %num (e.g. 0)
+define void @test_zext_sext_num(i8* %mem, i8 %num) {
+ %zext.num = zext i8 %num to i16
+ %sext.num = sext i8 %num to i16
+ %zext.sext.num = zext i16 %sext.num to i32
+ %sext.zext.num = sext i16 %zext.num to i32
+ %zext.zext.sext.num = zext i32 %zext.sext.num to i64
+ %zext.sext.zext.num = zext i32 %sext.zext.num to i64
+ %a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.num
+ %b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.num
+ ret void
+}
+
+; CHECK-LABEL: uncompressStream
+; CHECK: MustAlias: i8* %a, i8* %b
+; CHECK: NoAlias: i8* %a, i8* %c
+define void @uncompressStream(i8* %mem) {
+ %zext.255 = zext i8 255 to i32
+ %sext.255 = sext i8 255 to i32
+ %a = getelementptr inbounds i8, i8* %mem, i32 255
+ %b = getelementptr inbounds i8, i8* %mem, i32 %zext.255
+ %c = getelementptr inbounds i8, i8* %mem, i32 %sext.255
+ ret void
+}
+
+; CHECK-LABEL: constantOffsetHeuristic_i3_i32
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @constantOffsetHeuristic_i3_i32(i32* %mem, i3 %val) {
+ %zext.plus.7 = add nsw i3 %val, 7
+ %zext.plus.4 = add nsw i3 %val, 4
+ %zext.val = zext i3 %val to i32
+ %zext.4 = zext i3 %zext.plus.4 to i32
+ %zext.7 = zext i3 %zext.plus.7 to i32
+ %a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
+ %b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
+ %c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
+ ret void
+}
+
+; CHECK-LABEL: constantOffsetHeuristic_i8_i32
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @constantOffsetHeuristic_i8_i32(i32* %mem, i8 %val) {
+ %zext.plus.7 = add nsw i8 %val, 7
+ %zext.plus.4 = add nsw i8 %val, 4
+ %zext.val = zext i8 %val to i32
+ %zext.4 = zext i8 %zext.plus.4 to i32
+ %zext.7 = zext i8 %zext.plus.7 to i32
+ %a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
+ %b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
+ %c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
+ ret void
+}
+
+; CHECK-LABEL: constantOffsetHeuristic_i3_i8
+; CHECK: PartialAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: PartialAlias: i32* %b, i32* %c
+define void @constantOffsetHeuristic_i3_i8(i8* %mem, i3 %val) {
+ %zext.plus.7 = add nsw i3 %val, 7
+ %zext.plus.4 = add nsw i3 %val, 4
+ %zext.val = zext i3 %val to i32
+ %zext.4 = zext i3 %zext.plus.4 to i32
+ %zext.7 = zext i3 %zext.plus.7 to i32
+ %a.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.4
+ %b.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.7
+ %c.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.val
+ %a = bitcast i8* %a.8 to i32*
+ %b = bitcast i8* %b.8 to i32*
+ %c = bitcast i8* %c.8 to i32*
+ ret void
+}
+
+; CHECK-LABEL: constantOffsetHeuristic_i8_i8
+; CHECK: PartialAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) {
+ %zext.plus.7 = add nsw i8 %val, 7
+ %zext.plus.4 = add nsw i8 %val, 4
+ %zext.val = zext i8 %val to i32
+ %zext.4 = zext i8 %zext.plus.4 to i32
+ %zext.7 = zext i8 %zext.plus.7 to i32
+ %a.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.4
+ %b.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.7
+ %c.8 = getelementptr inbounds i8, i8* %mem, i32 %zext.val
+ %a = bitcast i8* %a.8 to i32*
+ %b = bitcast i8* %b.8 to i32*
+ %c = bitcast i8* %c.8 to i32*
+ ret void
+}
diff --git a/test/Analysis/BasicAA/sequential-gep.ll b/test/Analysis/BasicAA/sequential-gep.ll
new file mode 100644
index 000000000000..c17a782aa04b
--- /dev/null
+++ b/test/Analysis/BasicAA/sequential-gep.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: t1
+; CHECK: NoAlias: i32* %gep1, i32* %gep2
+define void @t1([8 x i32]* %p, i32 %addend, i32* %q) {
+ %knownnonzero = load i32, i32* %q, !range !0
+ %add = add nsw nuw i32 %addend, %knownnonzero
+ %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
+ %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
+ ret void
+}
+
+; CHECK: Function: t2
+; CHECK: PartialAlias: i32* %gep1, i32* %gep2
+define void @t2([8 x i32]* %p, i32 %addend, i32* %q) {
+ %knownnonzero = load i32, i32* %q, !range !0
+ %add = add nsw nuw i32 %addend, %knownnonzero
+ %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
+ %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
+ ret void
+}
+
+; CHECK: Function: t3
+; CHECK: MustAlias: i32* %gep1, i32* %gep2
+define void @t3([8 x i32]* %p, i32 %addend, i32* %q) {
+ %knownnonzero = load i32, i32* %q, !range !0
+ %add = add nsw nuw i32 %addend, %knownnonzero
+ %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
+ %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
+ ret void
+}
+
+; CHECK: Function: t4
+; CHECK: PartialAlias: i32* %gep1, i32* %gep2
+define void @t4([8 x i32]* %p, i32 %addend, i32* %q) {
+ %knownnonzero = load i32, i32* %q, !range !0
+ %add = add nsw nuw i32 %addend, %knownnonzero
+ %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
+ %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 %add, i32 %add
+ ret void
+}
+
+; CHECK: Function: t5
+; CHECK: PartialAlias: i32* %gep2, i64* %bc
+define void @t5([8 x i32]* %p, i32 %addend, i32* %q) {
+ %knownnonzero = load i32, i32* %q, !range !0
+ %add = add nsw nuw i32 %addend, %knownnonzero
+ %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
+ %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
+ %bc = bitcast i32* %gep1 to i64*
+ ret void
+}
+
+!0 = !{ i32 1, i32 5 }
diff --git a/test/Analysis/BasicAA/zext.ll b/test/Analysis/BasicAA/zext.ll
new file mode 100644
index 000000000000..685d45be6151
--- /dev/null
+++ b/test/Analysis/BasicAA/zext.ll
@@ -0,0 +1,231 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK-LABEL: test_with_zext
+; CHECK: NoAlias: i8* %a, i8* %b
+
+define void @test_with_zext() {
+ %1 = tail call i8* @malloc(i64 120)
+ %a = getelementptr inbounds i8, i8* %1, i64 8
+ %2 = getelementptr inbounds i8, i8* %1, i64 16
+ %3 = zext i32 3 to i64
+ %b = getelementptr inbounds i8, i8* %2, i64 %3
+ ret void
+}
+
+; CHECK-LABEL: test_with_lshr
+; CHECK: NoAlias: i8* %a, i8* %b
+
+define void @test_with_lshr(i64 %i) {
+ %1 = tail call i8* @malloc(i64 120)
+ %a = getelementptr inbounds i8, i8* %1, i64 8
+ %2 = getelementptr inbounds i8, i8* %1, i64 16
+ %3 = lshr i64 %i, 2
+ %b = getelementptr inbounds i8, i8* %2, i64 %3
+ ret void
+}
+
+; CHECK-LABEL: test_with_a_loop
+; CHECK: NoAlias: i8* %a, i8* %b
+
+define void @test_with_a_loop(i8* %mem) {
+ br label %for.loop
+
+for.loop:
+ %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
+ %a = getelementptr inbounds i8, i8* %mem, i64 8
+ %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
+ %i.64 = zext i32 %i to i64
+ %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
+ %i.plus1 = add nuw nsw i32 %i, 1
+ %cmp = icmp eq i32 %i.plus1, 10
+ br i1 %cmp, label %for.loop.exit, label %for.loop
+
+for.loop.exit:
+ ret void
+}
+
+; CHECK-LABEL: test_with_varying_base_pointer_in_loop
+; CHECK: NoAlias: i8* %a, i8* %b
+
+define void @test_with_varying_base_pointer_in_loop(i8* %mem.orig) {
+ br label %for.loop
+
+for.loop:
+ %mem = phi i8* [ %mem.orig, %0 ], [ %mem.plus1, %for.loop ]
+ %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
+ %a = getelementptr inbounds i8, i8* %mem, i64 8
+ %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
+ %i.64 = zext i32 %i to i64
+ %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
+ %i.plus1 = add nuw nsw i32 %i, 1
+ %mem.plus1 = getelementptr inbounds i8, i8* %mem, i64 8
+ %cmp = icmp eq i32 %i.plus1, 10
+ br i1 %cmp, label %for.loop.exit, label %for.loop
+
+for.loop.exit:
+ ret void
+}
+
+; CHECK-LABEL: test_sign_extension
+; CHECK: PartialAlias: i64* %b.i64, i8* %a
+
+define void @test_sign_extension(i32 %p) {
+ %1 = tail call i8* @malloc(i64 120)
+ %p.64 = zext i32 %p to i64
+ %a = getelementptr inbounds i8, i8* %1, i64 %p.64
+ %p.minus1 = add i32 %p, -1
+ %p.minus1.64 = zext i32 %p.minus1 to i64
+ %b.i8 = getelementptr inbounds i8, i8* %1, i64 %p.minus1.64
+ %b.i64 = bitcast i8* %b.i8 to i64*
+ ret void
+}
+
+; CHECK-LABEL: test_fe_tools
+; CHECK: PartialAlias: i32* %a, i32* %b
+
+define void @test_fe_tools([8 x i32]* %values) {
+ br label %reorder
+
+for.loop:
+ %i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ]
+ %idxprom = zext i32 %i to i64
+ %b = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 %idxprom
+ %i.next = add nuw nsw i32 %i, 1
+ %1 = icmp eq i32 %i.next, 10
+ br i1 %1, label %for.loop.exit, label %for.loop
+
+reorder:
+ %a = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 1
+ br label %for.loop
+
+for.loop.exit:
+ ret void
+}
+
+@b = global i32 0, align 4
+@d = global i32 0, align 4
+
+; CHECK-LABEL: test_spec2006
+; CHECK: PartialAlias: i32** %x, i32** %y
+
+define void @test_spec2006() {
+ %h = alloca [1 x [2 x i32*]], align 16
+ %d.val = load i32, i32* @d, align 4
+ %d.promoted = sext i32 %d.val to i64
+ %1 = icmp slt i32 %d.val, 2
+ br i1 %1, label %.lr.ph, label %3
+
+.lr.ph: ; preds = %0
+ br label %2
+
+; <label>:2 ; preds = %.lr.ph, %2
+ %i = phi i32 [ %d.val, %.lr.ph ], [ %i.plus1, %2 ]
+ %i.promoted = sext i32 %i to i64
+ %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %d.promoted, i64 %i.promoted
+ %i.plus1 = add nsw i32 %i, 1
+ %cmp = icmp slt i32 %i.plus1, 2
+ br i1 %cmp, label %2, label %3
+
+; <label>:3 ; preds = %._crit_edge, %0
+ %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
+ ret void
+}
+
+; CHECK-LABEL: test_modulo_analysis_easy_case
+; CHECK: NoAlias: i32** %x, i32** %y
+
+define void @test_modulo_analysis_easy_case(i64 %i) {
+ %h = alloca [1 x [2 x i32*]], align 16
+ %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i, i64 0
+ %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
+ ret void
+}
+
+; CHECK-LABEL: test_modulo_analysis_in_loop
+; CHECK: NoAlias: i32** %x, i32** %y
+
+define void @test_modulo_analysis_in_loop() {
+ %h = alloca [1 x [2 x i32*]], align 16
+ br label %for.loop
+
+for.loop:
+ %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
+ %i.promoted = sext i32 %i to i64
+ %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 0
+ %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
+ %i.plus1 = add nsw i32 %i, 1
+ %cmp = icmp slt i32 %i.plus1, 2
+ br i1 %cmp, label %for.loop, label %for.loop.exit
+
+for.loop.exit:
+ ret void
+}
+
+; CHECK-LABEL: test_modulo_analysis_with_global
+; CHECK: PartialAlias: i32** %x, i32** %y
+
+define void @test_modulo_analysis_with_global() {
+ %h = alloca [1 x [2 x i32*]], align 16
+ %b = load i32, i32* @b, align 4
+ %b.promoted = sext i32 %b to i64
+ br label %for.loop
+
+for.loop:
+ %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
+ %i.promoted = sext i32 %i to i64
+ %x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 %b.promoted
+ %y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
+ %i.plus1 = add nsw i32 %i, 1
+ %cmp = icmp slt i32 %i.plus1, 2
+ br i1 %cmp, label %for.loop, label %for.loop.exit
+
+for.loop.exit:
+ ret void
+}
+
+; CHECK-LABEL: test_const_eval
+; CHECK: NoAlias: i8* %a, i8* %b
+define void @test_const_eval(i8* %ptr, i64 %offset) {
+ %a = getelementptr inbounds i8, i8* %ptr, i64 %offset
+ %a.dup = getelementptr inbounds i8, i8* %ptr, i64 %offset
+ %three = zext i32 3 to i64
+ %b = getelementptr inbounds i8, i8* %a.dup, i64 %three
+ ret void
+}
+
+; CHECK-LABEL: test_const_eval_scaled
+; CHECK: MustAlias: i8* %a, i8* %b
+define void @test_const_eval_scaled(i8* %ptr) {
+ %three = zext i32 3 to i64
+ %six = mul i64 %three, 2
+ %a = getelementptr inbounds i8, i8* %ptr, i64 %six
+ %b = getelementptr inbounds i8, i8* %ptr, i64 6
+ ret void
+}
+
+; CHECK-LABEL: Function: foo
+; CHECK: MustAlias: float* %arrayidx, float* %arrayidx4.84
+define float @foo(i32 *%A, float %rend, float** %wayar) {
+entry:
+ %x0 = load i32, i32* %A, align 4
+ %conv = sext i32 %x0 to i64
+ %mul = shl nsw i64 %conv, 3
+ %call = tail call i8* @malloc(i64 %mul)
+ %x1 = bitcast i8* %call to float*
+
+ %sub = add nsw i32 %x0, -1
+ %idxprom = sext i32 %sub to i64
+ %arrayidx = getelementptr inbounds float, float* %x1, i64 %idxprom
+ store float %rend, float* %arrayidx, align 8
+
+ %indvars.iv76.83 = add nsw i64 %conv, -1
+ %arrayidx4.84 = getelementptr inbounds float, float* %x1, i64 %indvars.iv76.83
+ %x4 = load float, float* %arrayidx4.84, align 8
+
+ ret float %x4
+}
+
+; Function Attrs: nounwind
+declare noalias i8* @malloc(i64)