1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s
2 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes -pointer-tbaa %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,ENABLED %s
3 // RUN: %clang --target=x86_64-apple-darwin -O1 %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s
4 // RUN: %clang --target=x86_64-apple-darwin -O1 -fpointer-tbaa %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,ENABLED %s
6 void p2unsigned(unsigned **ptr
) {
7 // COMMON-LABEL: define void @p2unsigned(
8 // COMMON-SAME: ptr noundef [[PTR:%.+]])
9 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
10 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0:!.+]]
11 // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]]
12 // ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]]
13 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]]
14 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
15 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
16 // COMMON-NEXT: ret void
21 void p2unsigned_volatile(unsigned *volatile *ptr
) {
22 // COMMON-LABEL: define void @p2unsigned_volatile(
23 // COMMON-SAME: ptr noundef [[PTR:%.+]])
24 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
25 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]]
26 // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]]
27 // ENABLED-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0]]
28 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
29 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
30 // DEFAULT-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
31 // COMMON-NEXT: ret void
36 void p3int(int ***ptr
) {
37 // COMMON-LABEL: define void @p3int(
38 // COMMON-SAME: ptr noundef [[PTR:%.+]])
39 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
40 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0:!.+]]
41 // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0]]
42 // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P2INT_0]]
43 // ENABLED-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[P1INT_0]]
44 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
45 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
46 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]]
47 // DEFAULT-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]]
48 // COMMON-NEXT: ret void
53 void p4char(char ****ptr
) {
54 // COMMON-LABEL: define void @p4char(
55 // COMMON-SAME: ptr noundef [[PTR:%.+]])
56 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
57 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0:!.+]]
58 // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]]
59 // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0:!.+]]
60 // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0:!.+]]
61 // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0:!.+]]
62 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
63 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
64 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]]
65 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]]
66 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]]
67 // COMMON-NEXT: ret void
72 void p4char_const1(const char ****ptr
) {
73 // COMMON-LABEL: define void @p4char_const1(
74 // COMMON-SAME: ptr noundef [[PTR:%.+]])
75 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
76 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]]
77 // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]]
78 // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]]
79 // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]]
80 // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]]
81 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
82 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
83 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]]
84 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]]
85 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]]
86 // COMMON-NEXT: ret void
91 void p4char_const2(const char **const **ptr
) {
92 // COMMON-LABEL: define void @p4char_const2(
93 // COMMON-SAME: ptr noundef [[PTR:%.+]])
94 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
95 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]]
96 // ENABLED-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]]
97 // ENABLED-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]]
98 // ENABLED-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]]
99 // ENABLED-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]]
100 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
101 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
102 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]]
103 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]]
104 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]]
105 // COMMON-NEXT: ret void
115 void p2struct(struct S1
**ptr
) {
116 // COMMON-LABEL: define void @p2struct(
117 // COMMON-SAME: ptr noundef [[PTR:%.+]])
118 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
119 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG:!.+]]
120 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
121 // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG]]
122 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
123 // ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG:!.+]]
124 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
125 // COMMON-NEXT: ret void
130 void p2struct_const(struct S1
const **ptr
) {
131 // COMMON-LABEL: define void @p2struct_const(
132 // COMMON-SAME: ptr noundef [[PTR:%.+]])
133 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
134 // COMMON-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]]
135 // COMMON-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
136 // ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG]]
137 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
138 // COMMON-NEXT: ret void
147 void p2struct2(struct S2
*ptr
) {
148 // COMMON-LABEL: define void @p2struct2(
149 // COMMON-SAME: ptr noundef [[PTR:%.+]])
150 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
151 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG:!.+]]
152 // ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG]]
153 // ENABLED-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0
154 // ENABLED-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]]
155 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
156 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
157 // DEFAULT-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0
158 // DEFAULT-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]]
159 // COMMON-NEXT: ret void
164 void vla1(int n
, int ptr
[][n
], int idx
) {
165 // COMMON-LABEL: define void @vla1(
166 // COMMON-SAME: i32 noundef [[N:%.+]], ptr noundef [[PTR:%.+]], i32 noundef [[IDX:%.+]])
167 // COMMON: [[N_ADDR:%.+]] = alloca i32, align 4
168 // COMMON-NEXT: [[PTR_ADDR:%.+]] = alloca ptr, align 8
169 // COMMON-NEXT: [[IDX_ADDR:%.+]] = alloca i32, align 4
170 // COMMON-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4, !tbaa [[INT_TY:!.+]]
171 // ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1INT0:!.+]]
172 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
173 // COMMON-NEXT: store i32 [[IDX]], ptr [[IDX_ADDR]], align 4, !tbaa [[INT_TY]]
174 // COMMON-NEXT: [[L:%.+]] = load i32, ptr [[N_ADDR]], align 4, !tbaa [[INT_TY]]
175 // COMMON-NEXT: [[L_EXT:%.+]] = zext i32 [[L]] to i64
176 // ENABLED-NEXT: [[L_PTR:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1INT0]]
177 // DEFAULT-NEXT: [[L_PTR:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
178 // COMMON-NEXT: [[L_IDX:%.+]] = load i32, ptr [[IDX_ADDR]], align 4, !tbaa [[INT_TY]]
179 // COMMON-NEXT: [[IDX_EXT:%.+]] = sext i32 [[L_IDX]] to i64
180 // COMMON-NEXT: [[MUL:%.+]] = mul nsw i64 [[IDX_EXT]], [[L_EXT]]
181 // COMMON-NEXT: [[GEP1:%.+]] = getelementptr inbounds i32, ptr [[L_PTR]], i64 [[MUL]]
182 // COMMON-NEXT: [[GEP2:%.+]] = getelementptr inbounds i32, ptr [[GEP1]], i64 0
183 // COMMON-NEXT: store i32 0, ptr [[GEP2]], align 4, !tbaa [[INT_TAG:!.+]]
184 // ENABLED-NEXT: ret void
193 void unamed_struct_typedef(TypedefS
*ptr
) {
194 // COMMON-LABEL: define void @unamed_struct_typedef(
195 // COMMON-SAME: ptr noundef [[PTRA:%.+]])
196 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
197 // DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
198 // DEFAULT-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
199 // ENABLED-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1TYPEDEF:!.+]]
200 // ENABLED-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1TYPEDEF]]
201 // COMMON-NEXT: [[GEP:%.+]] = getelementptr inbounds nuw %struct.TypedefS, ptr [[L0]], i32 0, i32 0
202 // COMMON-NEXT: store i32 0, ptr [[GEP]], align 4
203 // COMMON-NEXT: ret void
208 // ENABLED: [[P2INT_0]] = !{[[P2INT:!.+]], [[P2INT]], i64 0}
209 // ENABLED: [[P2INT]] = !{!"p2 int", [[ANY_POINTER:!.+]], i64 0}
210 // DEFAULT: [[ANYPTR]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0}
211 // COMMON: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0}
212 // COMMON: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0}
213 // COMMON: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"}
214 // ENABLED: [[P1INT_0]] = !{[[P1INT:!.+]], [[P1INT]], i64 0}
215 // ENABLED: [[P1INT]] = !{!"p1 int", [[ANY_POINTER]], i64 0}
216 // ENABLED: [[P3INT_0]] = !{[[P3INT:!.+]], [[P3INT]], i64 0}
217 // ENABLED: [[P3INT]] = !{!"p3 int", [[ANY_POINTER]], i64 0}
218 // ENABLED: [[P4CHAR_0]] = !{[[P4CHAR:!.+]], [[P4CHAR]], i64 0}
219 // ENABLED: [[P4CHAR]] = !{!"p4 omnipotent char", [[ANY_POINTER]], i64 0}
220 // ENABLED: [[P3CHAR_0]] = !{[[P3CHAR:!.+]], [[P3CHAR]], i64 0}
221 // ENABLED: [[P3CHAR]] = !{!"p3 omnipotent char", [[ANY_POINTER]], i64 0}
222 // ENABLED: [[P2CHAR_0]] = !{[[P2CHAR:!.+]], [[P2CHAR]], i64 0}
223 // ENABLED: [[P2CHAR]] = !{!"p2 omnipotent char", [[ANY_POINTER]], i64 0}
224 // ENABLED: [[P1CHAR_0]] = !{[[P1CHAR:!.+]], [[P1CHAR]], i64 0}
225 // ENABLED: [[P1CHAR]] = !{!"p1 omnipotent char", [[ANY_POINTER]], i64 0}
226 // ENABLED: [[P2S1_TAG]] = !{[[P2S1:!.+]], [[P2S1]], i64 0}
227 // ENABLED: [[P2S1]] = !{!"p2 _ZTS2S1", [[ANY_POINTER]], i64 0}
228 // ENABLED: [[P1S1_TAG:!.+]] = !{[[P1S1:!.+]], [[P1S1]], i64 0}
229 // ENABLED: [[P1S1]] = !{!"p1 _ZTS2S1", [[ANY_POINTER]], i64 0}
230 // ENABLED: [[P1S2_TAG]] = !{[[P1S2:!.+]], [[P1S2]], i64 0}
231 // ENABLED: [[P1S2]] = !{!"p1 _ZTS2S2", [[ANY_POINTER]], i64 0}
233 // ENABLED: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[P1S1]], i64 0}
234 // ENABLED: [[S2_TY]] = !{!"S2", [[P1S1]], i64 0}
235 // DEFAULT: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[ANY_POINTER]], i64 0}
236 // DEFAULT: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0}
237 // COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0}
238 // COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0}
239 // ENABLED: [[P1TYPEDEF]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0}