1; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s 2; RUN: opt < %s -tbaa -basicaa -gvn -S | FileCheck %s --check-prefix=OPT 3; Generated from clang/test/CodeGen/tbaa.cpp with "-O1 -struct-path-tbaa -disable-llvm-optzns". 4 5%struct.StructA = type { i16, i32, i16, i32 } 6%struct.StructB = type { i16, %struct.StructA, i32 } 7%struct.StructS = type { i16, i32 } 8%struct.StructS2 = type { i16, i32 } 9%struct.StructC = type { i16, %struct.StructB, i32 } 10%struct.StructD = type { i16, %struct.StructB, i32, i8 } 11 12define i32 @_Z1gPjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 { 13entry: 14; Access to i32* and &(A->f32). 15; CHECK: Function 16; CHECK: MayAlias: store i32 4, i32* %f32, align 4, !tbaa !8 <-> store i32 1, i32* %0, align 4, !tbaa !6 17; OPT: define 18; OPT: store i32 1 19; OPT: store i32 4 20; OPT: %[[RET:.*]] = load i32* 21; OPT: ret i32 %[[RET]] 22 %s.addr = alloca i32*, align 8 23 %A.addr = alloca %struct.StructA*, align 8 24 %count.addr = alloca i64, align 8 25 store i32* %s, i32** %s.addr, align 8, !tbaa !0 26 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 27 store i64 %count, i64* %count.addr, align 8, !tbaa !4 28 %0 = load i32** %s.addr, align 8, !tbaa !0 29 store i32 1, i32* %0, align 4, !tbaa !6 30 %1 = load %struct.StructA** %A.addr, align 8, !tbaa !0 31 %f32 = getelementptr inbounds %struct.StructA* %1, i32 0, i32 1 32 store i32 4, i32* %f32, align 4, !tbaa !8 33 %2 = load i32** %s.addr, align 8, !tbaa !0 34 %3 = load i32* %2, align 4, !tbaa !6 35 ret i32 %3 36} 37 38define i32 @_Z2g2PjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 { 39entry: 40; Access to i32* and &(A->f16). 41; CHECK: Function 42; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !8 <-> store i32 1, i32* %0, align 4, !tbaa !6 43; OPT: define 44; OPT: store i32 1 45; OPT: store i16 4 46; Remove a load and propagate the value from store. 47; OPT: ret i32 1 48 %s.addr = alloca i32*, align 8 49 %A.addr = alloca %struct.StructA*, align 8 50 %count.addr = alloca i64, align 8 51 store i32* %s, i32** %s.addr, align 8, !tbaa !0 52 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 53 store i64 %count, i64* %count.addr, align 8, !tbaa !4 54 %0 = load i32** %s.addr, align 8, !tbaa !0 55 store i32 1, i32* %0, align 4, !tbaa !6 56 %1 = load %struct.StructA** %A.addr, align 8, !tbaa !0 57 %f16 = getelementptr inbounds %struct.StructA* %1, i32 0, i32 0 58 store i16 4, i16* %f16, align 2, !tbaa !11 59 %2 = load i32** %s.addr, align 8, !tbaa !0 60 %3 = load i32* %2, align 4, !tbaa !6 61 ret i32 %3 62} 63 64define i32 @_Z2g3P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 { 65entry: 66; Access to &(A->f32) and &(B->a.f32). 67; CHECK: Function 68; CHECK: MayAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 69; OPT: define 70; OPT: store i32 1 71; OPT: store i32 4 72; OPT: %[[RET:.*]] = load i32* 73; OPT: ret i32 %[[RET]] 74 %A.addr = alloca %struct.StructA*, align 8 75 %B.addr = alloca %struct.StructB*, align 8 76 %count.addr = alloca i64, align 8 77 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 78 store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0 79 store i64 %count, i64* %count.addr, align 8, !tbaa !4 80 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 81 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 82 store i32 1, i32* %f32, align 4, !tbaa !8 83 %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0 84 %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1 85 %f321 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1 86 store i32 4, i32* %f321, align 4, !tbaa !12 87 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 88 %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 89 %3 = load i32* %f322, align 4, !tbaa !8 90 ret i32 %3 91} 92 93define i32 @_Z2g4P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 { 94entry: 95; Access to &(A->f32) and &(B->a.f16). 96; CHECK: Function 97; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 98; OPT: define 99; OPT: store i32 1 100; OPT: store i16 4 101; Remove a load and propagate the value from store. 102; OPT: ret i32 1 103 %A.addr = alloca %struct.StructA*, align 8 104 %B.addr = alloca %struct.StructB*, align 8 105 %count.addr = alloca i64, align 8 106 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 107 store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0 108 store i64 %count, i64* %count.addr, align 8, !tbaa !4 109 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 110 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 111 store i32 1, i32* %f32, align 4, !tbaa !8 112 %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0 113 %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1 114 %f16 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 0 115 store i16 4, i16* %f16, align 2, !tbaa !14 116 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 117 %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 118 %3 = load i32* %f321, align 4, !tbaa !8 119 ret i32 %3 120} 121 122define i32 @_Z2g5P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 { 123entry: 124; Access to &(A->f32) and &(B->f32). 125; CHECK: Function 126; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 127; OPT: define 128; OPT: store i32 1 129; OPT: store i32 4 130; Remove a load and propagate the value from store. 131; OPT: ret i32 1 132 %A.addr = alloca %struct.StructA*, align 8 133 %B.addr = alloca %struct.StructB*, align 8 134 %count.addr = alloca i64, align 8 135 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 136 store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0 137 store i64 %count, i64* %count.addr, align 8, !tbaa !4 138 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 139 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 140 store i32 1, i32* %f32, align 4, !tbaa !8 141 %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0 142 %f321 = getelementptr inbounds %struct.StructB* %1, i32 0, i32 2 143 store i32 4, i32* %f321, align 4, !tbaa !15 144 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 145 %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 146 %3 = load i32* %f322, align 4, !tbaa !8 147 ret i32 %3 148} 149 150define i32 @_Z2g6P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 { 151entry: 152; Access to &(A->f32) and &(B->a.f32_2). 153; CHECK: Function 154; CHECK: NoAlias: store i32 4, i32* %f32_2, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 155; OPT: define 156; OPT: store i32 1 157; OPT: store i32 4 158; Remove a load and propagate the value from store. 159; OPT: ret i32 1 160 %A.addr = alloca %struct.StructA*, align 8 161 %B.addr = alloca %struct.StructB*, align 8 162 %count.addr = alloca i64, align 8 163 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 164 store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0 165 store i64 %count, i64* %count.addr, align 8, !tbaa !4 166 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 167 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 168 store i32 1, i32* %f32, align 4, !tbaa !8 169 %1 = load %struct.StructB** %B.addr, align 8, !tbaa !0 170 %a = getelementptr inbounds %struct.StructB* %1, i32 0, i32 1 171 %f32_2 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 3 172 store i32 4, i32* %f32_2, align 4, !tbaa !16 173 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 174 %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 175 %3 = load i32* %f321, align 4, !tbaa !8 176 ret i32 %3 177} 178 179define i32 @_Z2g7P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 { 180entry: 181; Access to &(A->f32) and &(S->f32). 182; CHECK: Function 183; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 184; OPT: define 185; OPT: store i32 1 186; OPT: store i32 4 187; Remove a load and propagate the value from store. 188; OPT: ret i32 1 189 %A.addr = alloca %struct.StructA*, align 8 190 %S.addr = alloca %struct.StructS*, align 8 191 %count.addr = alloca i64, align 8 192 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 193 store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0 194 store i64 %count, i64* %count.addr, align 8, !tbaa !4 195 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 196 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 197 store i32 1, i32* %f32, align 4, !tbaa !8 198 %1 = load %struct.StructS** %S.addr, align 8, !tbaa !0 199 %f321 = getelementptr inbounds %struct.StructS* %1, i32 0, i32 1 200 store i32 4, i32* %f321, align 4, !tbaa !17 201 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 202 %f322 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 203 %3 = load i32* %f322, align 4, !tbaa !8 204 ret i32 %3 205} 206 207define i32 @_Z2g8P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 { 208entry: 209; Access to &(A->f32) and &(S->f16). 210; CHECK: Function 211; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 212; OPT: define 213; OPT: store i32 1 214; OPT: store i16 4 215; Remove a load and propagate the value from store. 216; OPT: ret i32 1 217 %A.addr = alloca %struct.StructA*, align 8 218 %S.addr = alloca %struct.StructS*, align 8 219 %count.addr = alloca i64, align 8 220 store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0 221 store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0 222 store i64 %count, i64* %count.addr, align 8, !tbaa !4 223 %0 = load %struct.StructA** %A.addr, align 8, !tbaa !0 224 %f32 = getelementptr inbounds %struct.StructA* %0, i32 0, i32 1 225 store i32 1, i32* %f32, align 4, !tbaa !8 226 %1 = load %struct.StructS** %S.addr, align 8, !tbaa !0 227 %f16 = getelementptr inbounds %struct.StructS* %1, i32 0, i32 0 228 store i16 4, i16* %f16, align 2, !tbaa !19 229 %2 = load %struct.StructA** %A.addr, align 8, !tbaa !0 230 %f321 = getelementptr inbounds %struct.StructA* %2, i32 0, i32 1 231 %3 = load i32* %f321, align 4, !tbaa !8 232 ret i32 %3 233} 234 235define i32 @_Z2g9P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 { 236entry: 237; Access to &(S->f32) and &(S2->f32). 238; CHECK: Function 239; CHECK: NoAlias: store i32 4, i32* %f321, align 4, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 240; OPT: define 241; OPT: store i32 1 242; OPT: store i32 4 243; Remove a load and propagate the value from store. 244; OPT: ret i32 1 245 %S.addr = alloca %struct.StructS*, align 8 246 %S2.addr = alloca %struct.StructS2*, align 8 247 %count.addr = alloca i64, align 8 248 store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0 249 store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0 250 store i64 %count, i64* %count.addr, align 8, !tbaa !4 251 %0 = load %struct.StructS** %S.addr, align 8, !tbaa !0 252 %f32 = getelementptr inbounds %struct.StructS* %0, i32 0, i32 1 253 store i32 1, i32* %f32, align 4, !tbaa !17 254 %1 = load %struct.StructS2** %S2.addr, align 8, !tbaa !0 255 %f321 = getelementptr inbounds %struct.StructS2* %1, i32 0, i32 1 256 store i32 4, i32* %f321, align 4, !tbaa !20 257 %2 = load %struct.StructS** %S.addr, align 8, !tbaa !0 258 %f322 = getelementptr inbounds %struct.StructS* %2, i32 0, i32 1 259 %3 = load i32* %f322, align 4, !tbaa !17 260 ret i32 %3 261} 262 263define i32 @_Z3g10P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 { 264entry: 265; Access to &(S->f32) and &(S2->f16). 266; CHECK: Function 267; CHECK: NoAlias: store i16 4, i16* %f16, align 2, !tbaa !10 <-> store i32 1, i32* %f32, align 4, !tbaa !6 268; OPT: define 269; OPT: store i32 1 270; OPT: store i16 4 271; Remove a load and propagate the value from store. 272; OPT: ret i32 1 273 %S.addr = alloca %struct.StructS*, align 8 274 %S2.addr = alloca %struct.StructS2*, align 8 275 %count.addr = alloca i64, align 8 276 store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0 277 store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0 278 store i64 %count, i64* %count.addr, align 8, !tbaa !4 279 %0 = load %struct.StructS** %S.addr, align 8, !tbaa !0 280 %f32 = getelementptr inbounds %struct.StructS* %0, i32 0, i32 1 281 store i32 1, i32* %f32, align 4, !tbaa !17 282 %1 = load %struct.StructS2** %S2.addr, align 8, !tbaa !0 283 %f16 = getelementptr inbounds %struct.StructS2* %1, i32 0, i32 0 284 store i16 4, i16* %f16, align 2, !tbaa !22 285 %2 = load %struct.StructS** %S.addr, align 8, !tbaa !0 286 %f321 = getelementptr inbounds %struct.StructS* %2, i32 0, i32 1 287 %3 = load i32* %f321, align 4, !tbaa !17 288 ret i32 %3 289} 290 291define i32 @_Z3g11P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 { 292entry: 293; Access to &(C->b.a.f32) and &(D->b.a.f32). 294; CHECK: Function 295; CHECK: NoAlias: store i32 4, i32* %f323, align 4, !tbaa !12 <-> store i32 1, i32* %f32, align 4, !tbaa !6 296; OPT: define 297; OPT: store i32 1 298; OPT: store i32 4 299; Remove a load and propagate the value from store. 300; OPT: ret i32 1 301 %C.addr = alloca %struct.StructC*, align 8 302 %D.addr = alloca %struct.StructD*, align 8 303 %count.addr = alloca i64, align 8 304 store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0 305 store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0 306 store i64 %count, i64* %count.addr, align 8, !tbaa !4 307 %0 = load %struct.StructC** %C.addr, align 8, !tbaa !0 308 %b = getelementptr inbounds %struct.StructC* %0, i32 0, i32 1 309 %a = getelementptr inbounds %struct.StructB* %b, i32 0, i32 1 310 %f32 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1 311 store i32 1, i32* %f32, align 4, !tbaa !23 312 %1 = load %struct.StructD** %D.addr, align 8, !tbaa !0 313 %b1 = getelementptr inbounds %struct.StructD* %1, i32 0, i32 1 314 %a2 = getelementptr inbounds %struct.StructB* %b1, i32 0, i32 1 315 %f323 = getelementptr inbounds %struct.StructA* %a2, i32 0, i32 1 316 store i32 4, i32* %f323, align 4, !tbaa !25 317 %2 = load %struct.StructC** %C.addr, align 8, !tbaa !0 318 %b4 = getelementptr inbounds %struct.StructC* %2, i32 0, i32 1 319 %a5 = getelementptr inbounds %struct.StructB* %b4, i32 0, i32 1 320 %f326 = getelementptr inbounds %struct.StructA* %a5, i32 0, i32 1 321 %3 = load i32* %f326, align 4, !tbaa !23 322 ret i32 %3 323} 324 325define i32 @_Z3g12P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 { 326entry: 327; Access to &(b1->a.f32) and &(b2->a.f32). 328; CHECK: Function 329; CHECK: MayAlias: store i32 4, i32* %f325, align 4, !tbaa !6 <-> store i32 1, i32* %f32, align 4, !tbaa !6 330; OPT: define 331; OPT: store i32 1 332; OPT: store i32 4 333; OPT: %[[RET:.*]] = load i32* 334; OPT: ret i32 %[[RET]] 335 %C.addr = alloca %struct.StructC*, align 8 336 %D.addr = alloca %struct.StructD*, align 8 337 %count.addr = alloca i64, align 8 338 %b1 = alloca %struct.StructB*, align 8 339 %b2 = alloca %struct.StructB*, align 8 340 store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0 341 store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0 342 store i64 %count, i64* %count.addr, align 8, !tbaa !4 343 %0 = load %struct.StructC** %C.addr, align 8, !tbaa !0 344 %b = getelementptr inbounds %struct.StructC* %0, i32 0, i32 1 345 store %struct.StructB* %b, %struct.StructB** %b1, align 8, !tbaa !0 346 %1 = load %struct.StructD** %D.addr, align 8, !tbaa !0 347 %b3 = getelementptr inbounds %struct.StructD* %1, i32 0, i32 1 348 store %struct.StructB* %b3, %struct.StructB** %b2, align 8, !tbaa !0 349 %2 = load %struct.StructB** %b1, align 8, !tbaa !0 350 %a = getelementptr inbounds %struct.StructB* %2, i32 0, i32 1 351 %f32 = getelementptr inbounds %struct.StructA* %a, i32 0, i32 1 352 store i32 1, i32* %f32, align 4, !tbaa !12 353 %3 = load %struct.StructB** %b2, align 8, !tbaa !0 354 %a4 = getelementptr inbounds %struct.StructB* %3, i32 0, i32 1 355 %f325 = getelementptr inbounds %struct.StructA* %a4, i32 0, i32 1 356 store i32 4, i32* %f325, align 4, !tbaa !12 357 %4 = load %struct.StructB** %b1, align 8, !tbaa !0 358 %a6 = getelementptr inbounds %struct.StructB* %4, i32 0, i32 1 359 %f327 = getelementptr inbounds %struct.StructA* %a6, i32 0, i32 1 360 %5 = load i32* %f327, align 4, !tbaa !12 361 ret i32 %5 362} 363 364attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 365 366!0 = !{!1, !1, i64 0} 367!1 = !{!"any pointer", !2} 368!2 = !{!"omnipotent char", !3} 369!3 = !{!"Simple C/C++ TBAA"} 370!4 = !{!5, !5, i64 0} 371!5 = !{!"long long", !2} 372!6 = !{!7, !7, i64 0} 373!7 = !{!"int", !2} 374!8 = !{!9, !7, i64 4} 375!9 = !{!"_ZTS7StructA", !10, i64 0, !7, i64 4, !10, i64 8, !7, i64 12} 376!10 = !{!"short", !2} 377!11 = !{!9, !10, i64 0} 378!12 = !{!13, !7, i64 8} 379!13 = !{!"_ZTS7StructB", !10, i64 0, !9, i64 4, !7, i64 20} 380!14 = !{!13, !10, i64 4} 381!15 = !{!13, !7, i64 20} 382!16 = !{!13, !7, i64 16} 383!17 = !{!18, !7, i64 4} 384!18 = !{!"_ZTS7StructS", !10, i64 0, !7, i64 4} 385!19 = !{!18, !10, i64 0} 386!20 = !{!21, !7, i64 4} 387!21 = !{!"_ZTS8StructS2", !10, i64 0, !7, i64 4} 388!22 = !{!21, !10, i64 0} 389!23 = !{!24, !7, i64 12} 390!24 = !{!"_ZTS7StructC", !10, i64 0, !13, i64 4, !7, i64 28} 391!25 = !{!26, !7, i64 12} 392!26 = !{!"_ZTS7StructD", !10, i64 0, !13, i64 4, !7, i64 28, !2, i64 32} 393