1 ; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata \ 2 ; RUN: -print-no-aliases -print-may-aliases -disable-output 2>&1 | \ 3 ; RUN: FileCheck %s 4 ; RUN: opt < %s -tbaa -basicaa -gvn -S | FileCheck %s --check-prefix=OPT 5 ; 6 ; Check that TBAA handles access tags with aggregate final access types 7 ; correctly. 8 9 %A = type { i32 } ; struct A { int i; }; 10 %B = type { %A } ; struct B { A a; }; 11 %C = type { %B } ; struct C { B b; }; 12 %D = type { i16 } ; struct D { short s; }; 13 14 ; int vs. A::i => MayAlias. 15 define i32 @f1(i32* %i, %A* %a) { 16 entry: 17 ; CHECK-LABEL: f1 18 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5, 19 ; OPT-LABEL: f1 20 ; OPT: store i32 5, 21 ; OPT: store i32 7, 22 ; OPT: %[[RET:.*]] = load i32, 23 ; OPT: ret i32 %[[RET]] 24 store i32 5, i32* %i, align 4, !tbaa !3 ; TAG_int 25 %A_i = getelementptr inbounds %A, %A* %a, i64 0, i32 0 26 store i32 7, i32* %A_i, align 4, !tbaa !5 ; TAG_A_i 27 %0 = load i32, i32* %i, align 4, !tbaa !3 ; TAG_int 28 ret i32 %0 29 } 30 31 ; int vs. B::a => MayAlias. 32 define i32 @f2(i32* %i, %B* %b) { 33 entry: 34 ; CHECK-LABEL: f2 35 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5, 36 ; OPT-LABEL: f2 37 ; OPT: store i32 5, 38 ; OPT: store i32 7, 39 ; OPT: %[[RET:.*]] = load i32, 40 ; OPT: ret i32 %[[RET]] 41 store i32 5, i32* %i, align 4, !tbaa !3 ; TAG_int 42 %B_a = getelementptr inbounds %B, %B* %b, i64 0, i32 0, i32 0 43 store i32 7, i32* %B_a, align 4, !tbaa !7 ; TAG_B_a 44 %0 = load i32, i32* %i, align 4, !tbaa !3 ; TAG_int 45 ret i32 %0 46 } 47 48 ; int vs. C::b => MayAlias. 49 define i32 @f3(i32* %i, %C* %c) { 50 entry: 51 ; CHECK-LABEL: f3 52 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5, 53 ; OPT-LABEL: f3 54 ; OPT: store i32 5, 55 ; OPT: store i32 7, 56 ; OPT: %[[RET:.*]] = load i32, 57 ; OPT: ret i32 %[[RET]] 58 store i32 5, i32* %i, align 4, !tbaa !3 ; TAG_int 59 %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0 60 store i32 7, i32* %C_b, align 4, !tbaa !9 ; TAG_C_b 61 %0 = load i32, i32* %i, align 4, !tbaa !3 ; TAG_int 62 ret i32 %0 63 } 64 65 ; A vs. C::b => MayAlias. 66 define i32 @f4(%A* %a, %C* %c) { 67 entry: 68 ; CHECK-LABEL: f4 69 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5, 70 ; OPT-LABEL: f4 71 ; OPT: store i32 5, 72 ; OPT: store i32 7, 73 ; OPT: %[[RET:.*]] = load i32, 74 ; OPT: ret i32 %[[RET]] 75 %ap = getelementptr inbounds %A, %A* %a, i64 0, i32 0 76 store i32 5, i32* %ap, align 4, !tbaa !10 ; TAG_A 77 %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0 78 store i32 7, i32* %C_b, align 4, !tbaa !9 ; TAG_C_b 79 %0 = load i32, i32* %ap, align 4, !tbaa !10 ; TAG_A 80 ret i32 %0 81 } 82 83 ; short vs. C::b => NoAlias. 84 define i32 @f5(i32* %i, %C* %c) { 85 entry: 86 ; CHECK-LABEL: f5 87 ; CHECK: NoAlias: store i32 7, {{.*}} <-> store i32 5, 88 ; OPT-LABEL: f5 89 ; OPT: store i32 5, 90 ; OPT: store i32 7, 91 ; OPT: ret i32 5 92 store i32 5, i32* %i, align 4, !tbaa !12 ; TAG_short 93 %C_b = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0 94 store i32 7, i32* %C_b, align 4, !tbaa !9 ; TAG_C_b 95 %0 = load i32, i32* %i, align 4, !tbaa !12 ; TAG_short 96 ret i32 %0 97 } 98 99 ; C vs. D => NoAlias. 100 define i32 @f6(%C* %c, %D* %d) { 101 entry: 102 ; CHECK-LABEL: f6 103 ; CHECK: NoAlias: store i16 7, {{.*}} <-> store i32 5, 104 ; OPT-LABEL: f6 105 ; OPT: store i32 5, 106 ; OPT: store i16 7, 107 ; OPT: ret i32 5 108 %cp = getelementptr inbounds %C, %C* %c, i64 0, i32 0, i32 0, i32 0 109 store i32 5, i32* %cp, align 4, !tbaa !13 ; TAG_C 110 %dp = getelementptr inbounds %D, %D* %d, i64 0, i32 0 111 store i16 7, i16* %dp, align 4, !tbaa !15 ; TAG_D 112 %0 = load i32, i32* %cp, align 4, !tbaa !13 ; TAG_C 113 ret i32 %0 114 } 115 116 !0 = !{!"root"} 117 !1 = !{!0, i64 1, !"char"} 118 !2 = !{!1, i64 4, !"int"} 119 !3 = !{!2, !2, i64 0, i64 4} ; TAG_int 120 121 !4 = !{!1, i64 4, !"A", !2, i64 0, i64 4} 122 !5 = !{!4, !2, i64 0, i64 4} ; TAG_A_i 123 124 !6 = !{!1, i64 4, !"B", !4, i64 0, i64 4} 125 !7 = !{!6, !4, i64 0, i64 4} ; TAG_B_a 126 127 !8 = !{!1, i64 4, !"C", !6, i64 0, i64 4} 128 !9 = !{!8, !6, i64 0, i64 4} ; TAG_C_b 129 130 !10 = !{!4, !4, i64 0, i64 4} ; TAG_A 131 132 !11 = !{!1, i64 2, !"short"} 133 !12 = !{!11, !11, i64 0, i64 2} ; TAG_short 134 135 !13 = !{!8, !8, i64 0, i64 4} ; TAG_C 136 137 !14 = !{!4, i64 2, !"D", !11, i64 0, i64 2} 138 !15 = !{!14, !14, i64 0, i64 2} ; TAG_D 139