1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes -no-pointer-tbaa %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,DISABLE %s 2 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s 3 // RUN: %clang --target=x86_64-apple-darwin -O1 -fno-pointer-tbaa %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,DISABLE %s 4 // RUN: %clang --target=x86_64-apple-darwin -O1 %s -emit-llvm -S -mllvm -disable-llvm-optzns -o - | FileCheck --check-prefixes=COMMON,DEFAULT %s 5 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0:!.+]] 11 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] 12 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]] 13 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]] 14 // DISABLE-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 15 // DISABLE-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] 16 // COMMON-NEXT: ret void 17 // 18 *ptr = 0; 19 } 20 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] 26 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2INT_0]] 27 // DEFAULT-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0]] 28 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 29 // DISABLE-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 30 // DISABLE-NEXT: store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] 31 // COMMON-NEXT: ret void 32 // 33 *ptr = 0; 34 } 35 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0:!.+]] 41 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P3INT_0]] 42 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P2INT_0]] 43 // DEFAULT-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[P1INT_0]] 44 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 45 // DISABLE-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 46 // DISABLE-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] 47 // DISABLE-NEXT: store ptr null, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] 48 // COMMON-NEXT: ret void 49 // 50 **ptr = 0; 51 } 52 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0:!.+]] 58 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] 59 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0:!.+]] 60 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0:!.+]] 61 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0:!.+]] 62 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 63 // DISABLE-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 64 // DISABLE-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] 65 // DISABLE-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] 66 // DISABLE-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] 67 // COMMON-NEXT: ret void 68 // 69 ***ptr = 0; 70 } 71 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] 77 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] 78 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]] 79 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]] 80 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]] 81 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 82 // DISABLE-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 83 // DISABLE-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] 84 // DISABLE-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] 85 // DISABLE-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] 86 // COMMON-NEXT: ret void 87 // 88 ***ptr = 0; 89 } 90 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] 96 // DEFAULT-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P4CHAR_0]] 97 // DEFAULT-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]] 98 // DEFAULT-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]] 99 // DEFAULT-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]] 100 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 101 // DISABLE-NEXT: [[BASE_0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 102 // DISABLE-NEXT: [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANYPTR]] 103 // DISABLE-NEXT: [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANYPTR]] 104 // DISABLE-NEXT: store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANYPTR]] 105 // COMMON-NEXT: ret void 106 // 107 ***ptr = 0; 108 } 109 110 struct S1 { 111 int x; 112 int y; 113 }; 114 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG:!.+]] 120 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 121 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG]] 122 // DISABLE-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 123 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG:!.+]] 124 // DISABLE-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] 125 // COMMON-NEXT: ret void 126 // 127 *ptr = 0; 128 } 129 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 // DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG]] 137 // DISABLE-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]] 138 // COMMON-NEXT: ret void 139 // 140 *ptr = 0; 141 } 142 143 struct S2 { 144 struct S1 *s; 145 }; 146 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG:!.+]] 152 // DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG]] 153 // DEFAULT-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0 154 // DEFAULT-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]] 155 // DISABLE-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 156 // DISABLE-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 157 // DISABLE-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0 158 // DISABLE-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]] 159 // COMMON-NEXT: ret void 160 ptr->s = 0; 161 } 162 163 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 // DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1INT0:!.+]] 172 // DISABLE-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 // DEFAULT-NEXT: [[L_PTR:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1INT0]] 177 // DISABLE-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 // DEFAULT-NEXT: ret void 185 186 ptr[idx][0] = 0; 187 } 188 189 typedef struct { 190 int i1; 191 } TypedefS; 192 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 // DISABLE-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 198 // DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]] 199 // COMMON-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 200 // COMMON-NEXT: [[GEP:%.+]] = getelementptr inbounds nuw %struct.TypedefS, ptr [[L0]], i32 0, i32 0 201 // COMMON-NEXT: store i32 0, ptr [[GEP]], align 4 202 // COMMON-NEXT: ret void 203 204 ptr->i1 = 0; 205 } 206 207 int void_ptrs(void **ptr) { 208 // COMMON-LABEL: define i32 @void_ptrs( 209 // COMMON-SAME: ptr noundef [[PTRA:%.+]]) 210 // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 211 // DISABLE-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 212 // DISABLE-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] 213 // DISABLE-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]] 214 // DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID:!.+]] 215 // DEFAULT-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID]] 216 // DEFAULT-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[P1VOID:!.+]] 217 // COMMON-NEXT: [[BOOL:%.+]] = icmp ne ptr [[L1]], null 218 // COMMON-NEXT: [[BOOL_EXT:%.+]] = zext i1 [[BOOL]] to i64 219 // COMMON-NEXT: [[COND:%.+]] = select i1 [[BOOL]], i32 0, i32 1 220 // COMMON-NEXT: ret i32 [[COND]] 221 222 return *ptr ? 0 : 1; 223 } 224 225 // DEFAULT: [[P2INT_0]] = !{[[P2INT:!.+]], [[P2INT]], i64 0} 226 // DEFAULT: [[P2INT]] = !{!"p2 int", [[ANY_POINTER:!.+]], i64 0} 227 // DISABLE: [[ANYPTR]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0} 228 // COMMON: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0} 229 // COMMON: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0} 230 // COMMON: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"} 231 // DEFAULT: [[P1INT_0]] = !{[[P1INT:!.+]], [[P1INT]], i64 0} 232 // DEFAULT: [[P1INT]] = !{!"p1 int", [[ANY_POINTER]], i64 0} 233 // DEFAULT: [[P3INT_0]] = !{[[P3INT:!.+]], [[P3INT]], i64 0} 234 // DEFAULT: [[P3INT]] = !{!"p3 int", [[ANY_POINTER]], i64 0} 235 // DEFAULT: [[P4CHAR_0]] = !{[[P4CHAR:!.+]], [[P4CHAR]], i64 0} 236 // DEFAULT: [[P4CHAR]] = !{!"p4 omnipotent char", [[ANY_POINTER]], i64 0} 237 // DEFAULT: [[P3CHAR_0]] = !{[[P3CHAR:!.+]], [[P3CHAR]], i64 0} 238 // DEFAULT: [[P3CHAR]] = !{!"p3 omnipotent char", [[ANY_POINTER]], i64 0} 239 // DEFAULT: [[P2CHAR_0]] = !{[[P2CHAR:!.+]], [[P2CHAR]], i64 0} 240 // DEFAULT: [[P2CHAR]] = !{!"p2 omnipotent char", [[ANY_POINTER]], i64 0} 241 // DEFAULT: [[P1CHAR_0]] = !{[[P1CHAR:!.+]], [[P1CHAR]], i64 0} 242 // DEFAULT: [[P1CHAR]] = !{!"p1 omnipotent char", [[ANY_POINTER]], i64 0} 243 // DEFAULT: [[P2S1_TAG]] = !{[[P2S1:!.+]], [[P2S1]], i64 0} 244 // DEFAULT: [[P2S1]] = !{!"p2 _ZTS2S1", [[ANY_POINTER]], i64 0} 245 // DEFAULT: [[P1S1_TAG:!.+]] = !{[[P1S1:!.+]], [[P1S1]], i64 0} 246 // DEFAULT: [[P1S1]] = !{!"p1 _ZTS2S1", [[ANY_POINTER]], i64 0} 247 // DEFAULT: [[P1S2_TAG]] = !{[[P1S2:!.+]], [[P1S2]], i64 0} 248 // DEFAULT: [[P1S2]] = !{!"p1 _ZTS2S2", [[ANY_POINTER]], i64 0} 249 250 // DEFAULT: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[P1S1]], i64 0} 251 // DEFAULT: [[S2_TY]] = !{!"S2", [[P1S1]], i64 0} 252 // DISABLE: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[ANY_POINTER]], i64 0} 253 // DISABLE: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0} 254 // COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0} 255 // COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0} 256 // DEFAULT: [[ANYPTR]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0} 257 // DEFAULT: [[P2VOID]] = !{[[P2VOID_TY:!.+]], [[P2VOID_TY]], i64 0} 258 // DEFAULT: [[P2VOID_TY]] = !{!"p2 void", [[ANY_POINTER]], i64 0} 259 // DEFAULT: [[P1VOID]] = !{[[P1VOID_TY:!.+]], [[P1VOID_TY]], i64 0} 260 // DEFAULT: [[P1VOID_TY]] = !{!"p1 void", [[ANY_POINTER]], i64 0} 261