|
6 | 6 | ; Check that TBAA handles access tags with aggregate final access types |
7 | 7 | ; correctly. |
8 | 8 |
|
9 | | -%A = type { i32 } ; struct A { int i; }; |
| 9 | +%A = type { i32, i32 } ; struct A { int i, j; }; |
10 | 10 | %B = type { %A } ; struct B { A a; }; |
11 | 11 | %C = type { %B } ; struct C { B b; }; |
12 | 12 | %D = type { i16 } ; struct D { short s; }; |
@@ -105,13 +105,32 @@ entry: |
105 | 105 | ret i32 %0 |
106 | 106 | } |
107 | 107 |
|
| 108 | +; A vs. A::j => MayAlias. |
| 109 | +; This differs from A vs. A::i case in that the offsets of the final |
| 110 | +; accessed objects in A do not match. |
| 111 | +define i32 @f7(ptr %i, ptr %a) { |
| 112 | +entry: |
| 113 | +; CHECK-LABEL: f7 |
| 114 | +; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5, |
| 115 | +; OPT-LABEL: f7 |
| 116 | +; OPT: store i32 5, |
| 117 | +; OPT: store i32 7, |
| 118 | +; OPT: %[[RET:.*]] = load i32, |
| 119 | +; OPT: ret i32 %[[RET]] |
| 120 | + store i32 5, ptr %i, align 4, !tbaa !10 ; TAG_A |
| 121 | + store i32 7, ptr %a, align 4, !tbaa !16 ; TAG_A_j |
| 122 | + %0 = load i32, ptr %i, align 4, !tbaa !10 ; TAG_A |
| 123 | + ret i32 %0 |
| 124 | +} |
| 125 | + |
108 | 126 | !0 = !{!"root"} |
109 | 127 | !1 = !{!0, i64 1, !"char"} |
110 | 128 | !2 = !{!1, i64 4, !"int"} |
111 | 129 | !3 = !{!2, !2, i64 0, i64 4} ; TAG_int |
112 | 130 |
|
113 | | -!4 = !{!1, i64 4, !"A", !2, i64 0, i64 4} |
| 131 | +!4 = !{!1, i64 4, !"A", !2, i64 0, i64 4, !2, i64 4, i64 4} |
114 | 132 | !5 = !{!4, !2, i64 0, i64 4} ; TAG_A_i |
| 133 | +!16 = !{!4, !2, i64 4, i64 4} ; TAG_A_j |
115 | 134 |
|
116 | 135 | !6 = !{!1, i64 4, !"B", !4, i64 0, i64 4} |
117 | 136 | !7 = !{!6, !4, i64 0, i64 4} ; TAG_B_a |
|
0 commit comments