aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll')
-rw-r--r--test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll104
1 files changed, 104 insertions, 0 deletions
diff --git a/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
new file mode 100644
index 0000000000..f1edb4482c
--- /dev/null
+++ b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
@@ -0,0 +1,104 @@
+; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-tbaa -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; Generated with "clang -cc1 -disable-llvm-optzns -O1 -emit-llvm"
+; #include <new>
+; struct Foo { long i; };
+; struct Bar { void *p; };
+; long foo(int n) {
+; Foo *f = new Foo;
+; f->i = 1;
+; for (int i=0; i<n; ++i) {
+; Bar *b = new (f) Bar;
+; b->p = 0;
+; f = new (f) Foo;
+; f->i = i;
+; }
+; return f->i;
+; }
+
+; Basic AA says MayAlias, TBAA says NoAlias
+; CHECK: MayAlias: i64* %i5, i8** %p
+; CHECK: NoAlias: store i64 %conv, i64* %i5, align 8, !tbaa !4 <-> store i8* null, i8** %p, align 8, !tbaa !3
+
+%struct.Foo = type { i64 }
+%struct.Bar = type { i8* }
+
+define i64 @_Z3fooi(i32 %n) #0 {
+entry:
+ %n.addr = alloca i32, align 4
+ %f = alloca %struct.Foo*, align 8
+ %i1 = alloca i32, align 4
+ %b = alloca %struct.Bar*, align 8
+ store i32 %n, i32* %n.addr, align 4, !tbaa !0
+ %call = call noalias i8* @_Znwm(i64 8)
+ %0 = bitcast i8* %call to %struct.Foo*
+ store %struct.Foo* %0, %struct.Foo** %f, align 8, !tbaa !3
+ %1 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i = getelementptr inbounds %struct.Foo* %1, i32 0, i32 0
+ store i64 1, i64* %i, align 8, !tbaa !4
+ store i32 0, i32* %i1, align 4, !tbaa !0
+ br label %for.cond
+
+for.cond:
+ %2 = load i32* %i1, align 4, !tbaa !0
+ %3 = load i32* %n.addr, align 4, !tbaa !0
+ %cmp = icmp slt i32 %2, %3
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %4 = load %struct.Foo** %f, align 8, !tbaa !3
+ %5 = bitcast %struct.Foo* %4 to i8*
+ %new.isnull = icmp eq i8* %5, null
+ br i1 %new.isnull, label %new.cont, label %new.notnull
+
+new.notnull:
+ %6 = bitcast i8* %5 to %struct.Bar*
+ br label %new.cont
+
+new.cont:
+ %7 = phi %struct.Bar* [ %6, %new.notnull ], [ null, %for.body ]
+ store %struct.Bar* %7, %struct.Bar** %b, align 8, !tbaa !3
+ %8 = load %struct.Bar** %b, align 8, !tbaa !3
+ %p = getelementptr inbounds %struct.Bar* %8, i32 0, i32 0
+ store i8* null, i8** %p, align 8, !tbaa !3
+ %9 = load %struct.Foo** %f, align 8, !tbaa !3
+ %10 = bitcast %struct.Foo* %9 to i8*
+ %new.isnull2 = icmp eq i8* %10, null
+ br i1 %new.isnull2, label %new.cont4, label %new.notnull3
+
+new.notnull3:
+ %11 = bitcast i8* %10 to %struct.Foo*
+ br label %new.cont4
+
+new.cont4:
+ %12 = phi %struct.Foo* [ %11, %new.notnull3 ], [ null, %new.cont ]
+ store %struct.Foo* %12, %struct.Foo** %f, align 8, !tbaa !3
+ %13 = load i32* %i1, align 4, !tbaa !0
+ %conv = sext i32 %13 to i64
+ %14 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i5 = getelementptr inbounds %struct.Foo* %14, i32 0, i32 0
+ store i64 %conv, i64* %i5, align 8, !tbaa !4
+ br label %for.inc
+
+for.inc:
+ %15 = load i32* %i1, align 4, !tbaa !0
+ %inc = add nsw i32 %15, 1
+ store i32 %inc, i32* %i1, align 4, !tbaa !0
+ br label %for.cond
+
+for.end:
+ %16 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i6 = getelementptr inbounds %struct.Foo* %16, i32 0, i32 0
+ %17 = load i64* %i6, align 8, !tbaa !4
+ ret i64 %17
+}
+
+declare noalias i8* @_Znwm(i64)
+
+attributes #0 = { nounwind }
+
+!0 = metadata !{metadata !"int", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA"}
+!3 = metadata !{metadata !"any pointer", metadata !1}
+!4 = metadata !{metadata !"long", metadata !1}