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 -new-struct-path-tbaa". 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 12; uint32_t g(uint32_t *s, StructA *A, uint64_t count) { 13; *s = 1; 14; A->f32 = 4; 15; return *s; 16; } 17; 18define i32 @_Z1gPjP7StructAy(i32* nocapture %s, %struct.StructA* nocapture %A, i64 %count) { 19entry: 20; CHECK-LABEL: Z1gPjP7StructAy 21; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1, 22; OPT-LABEL: _Z1gPjP7StructAy 23; OPT: store i32 1, 24; OPT: store i32 4, 25; OPT: %[[RET:.*]] = load i32, 26; OPT: ret i32 %[[RET]] 27 store i32 1, i32* %s, align 4, !tbaa !2 28 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 29 store i32 4, i32* %f32, align 4, !tbaa !6 30 %0 = load i32, i32* %s, align 4, !tbaa !2 31 ret i32 %0 32} 33 34; uint32_t g2(uint32_t *s, StructA *A, uint64_t count) { 35; *s = 1; 36; A->f16 = 4; 37; return *s; 38; } 39; 40define i32 @_Z2g2PjP7StructAy(i32* nocapture %s, %struct.StructA* nocapture %A, i64 %count) { 41entry: 42; CHECK-LABEL: _Z2g2PjP7StructAy 43; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1, 44; OPT-LABEL: _Z2g2PjP7StructAy 45; OPT: store i32 1, 46; OPT: store i16 4, 47; Remove a load and propagate the value from store. 48; OPT: ret i32 1 49 store i32 1, i32* %s, align 4, !tbaa !2 50 %f16 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 0 51 store i16 4, i16* %f16, align 4, !tbaa !9 52 ret i32 1 53} 54 55; uint32_t g3(StructA *A, StructB *B, uint64_t count) { 56; A->f32 = 1; 57; B->a.f32 = 4; 58; return A->f32; 59; } 60; 61define i32 @_Z2g3P7StructAP7StructBy(%struct.StructA* nocapture %A, %struct.StructB* nocapture %B, i64 %count) { 62entry: 63; CHECK-LABEL: _Z2g3P7StructAP7StructBy 64; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1, 65; OPT-LABEL: _Z2g3P7StructAP7StructBy 66; OPT: store i32 1 67; OPT: store i32 4 68; OPT: %[[RET:.*]] = load i32, 69; OPT: ret i32 %[[RET]] 70 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 71 store i32 1, i32* %f32, align 4, !tbaa !6 72 %f321 = getelementptr inbounds %struct.StructB, %struct.StructB* %B, i64 0, i32 1, i32 1 73 store i32 4, i32* %f321, align 4, !tbaa !10 74 %0 = load i32, i32* %f32, align 4, !tbaa !6 75 ret i32 %0 76} 77 78; uint32_t g4(StructA *A, StructB *B, uint64_t count) { 79; A->f32 = 1; 80; B->a.f16 = 4; 81; return A->f32; 82; } 83; 84define i32 @_Z2g4P7StructAP7StructBy(%struct.StructA* nocapture %A, %struct.StructB* nocapture %B, i64 %count) { 85entry: 86; CHECK-LABEL: _Z2g4P7StructAP7StructBy 87; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1, 88; OPT-LABEL: _Z2g4P7StructAP7StructBy 89; OPT: store i32 1, 90; OPT: store i16 4, 91; Remove a load and propagate the value from store. 92; OPT: ret i32 1 93 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 94 store i32 1, i32* %f32, align 4, !tbaa !6 95 %f16 = getelementptr inbounds %struct.StructB, %struct.StructB* %B, i64 0, i32 1, i32 0 96 store i16 4, i16* %f16, align 4, !tbaa !12 97 ret i32 1 98} 99 100; uint32_t g5(StructA *A, StructB *B, uint64_t count) { 101; A->f32 = 1; 102; B->f32 = 4; 103; return A->f32; 104; } 105; 106define i32 @_Z2g5P7StructAP7StructBy(%struct.StructA* nocapture %A, %struct.StructB* nocapture %B, i64 %count) { 107entry: 108; CHECK-LABEL: _Z2g5P7StructAP7StructBy 109; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1, 110; OPT-LABEL: _Z2g5P7StructAP7StructBy 111; OPT: store i32 1, 112; OPT: store i32 4, 113; Remove a load and propagate the value from store. 114; OPT: ret i32 1 115 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 116 store i32 1, i32* %f32, align 4, !tbaa !6 117 %f321 = getelementptr inbounds %struct.StructB, %struct.StructB* %B, i64 0, i32 2 118 store i32 4, i32* %f321, align 4, !tbaa !13 119 ret i32 1 120} 121 122; uint32_t g6(StructA *A, StructB *B, uint64_t count) { 123; A->f32 = 1; 124; B->a.f32_2 = 4; 125; return A->f32; 126; } 127; 128define i32 @_Z2g6P7StructAP7StructBy(%struct.StructA* nocapture %A, %struct.StructB* nocapture %B, i64 %count) { 129entry: 130; CHECK-LABEL: _Z2g6P7StructAP7StructBy 131; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1, 132; OPT-LABEL: _Z2g6P7StructAP7StructBy 133; OPT: store i32 1, 134; OPT: store i32 4, 135; Remove a load and propagate the value from store. 136; OPT: ret i32 1 137 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 138 store i32 1, i32* %f32, align 4, !tbaa !6 139 %f32_2 = getelementptr inbounds %struct.StructB, %struct.StructB* %B, i64 0, i32 1, i32 3 140 store i32 4, i32* %f32_2, align 4, !tbaa !14 141 ret i32 1 142} 143 144; uint32_t g7(StructA *A, StructS *S, uint64_t count) { 145; A->f32 = 1; 146; S->f32 = 4; 147; return A->f32; 148; } 149; 150define i32 @_Z2g7P7StructAP7StructSy(%struct.StructA* nocapture %A, %struct.StructS* nocapture %S, i64 %count) { 151entry: 152; CHECK-LABEL: _Z2g7P7StructAP7StructSy 153; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1, 154; OPT-LABEL: _Z2g7P7StructAP7StructSy 155; OPT: store i32 1, 156; OPT: store i32 4, 157; Remove a load and propagate the value from store. 158; OPT: ret i32 1 159 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 160 store i32 1, i32* %f32, align 4, !tbaa !6 161 %f321 = getelementptr inbounds %struct.StructS, %struct.StructS* %S, i64 0, i32 1 162 store i32 4, i32* %f321, align 4, !tbaa !15 163 ret i32 1 164} 165 166; uint32_t g8(StructA *A, StructS *S, uint64_t count) { 167; A->f32 = 1; 168; S->f16 = 4; 169; return A->f32; 170; } 171; 172define i32 @_Z2g8P7StructAP7StructSy(%struct.StructA* nocapture %A, %struct.StructS* nocapture %S, i64 %count) { 173entry: 174; CHECK-LABEL: _Z2g8P7StructAP7StructSy 175; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1, 176; OPT-LABEL: _Z2g8P7StructAP7StructSy 177; OPT: store i32 1, 178; OPT: store i16 4, 179; Remove a load and propagate the value from store. 180; OPT: ret i32 1 181 %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %A, i64 0, i32 1 182 store i32 1, i32* %f32, align 4, !tbaa !6 183 %f16 = getelementptr inbounds %struct.StructS, %struct.StructS* %S, i64 0, i32 0 184 store i16 4, i16* %f16, align 4, !tbaa !17 185 ret i32 1 186} 187 188; uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) { 189; S->f32 = 1; 190; S2->f32 = 4; 191; return S->f32; 192; } 193; 194define i32 @_Z2g9P7StructSP8StructS2y(%struct.StructS* nocapture %S, %struct.StructS2* nocapture %S2, i64 %count) { 195entry: 196; CHECK-LABEL: _Z2g9P7StructSP8StructS2y 197; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1, 198; OPT-LABEL: _Z2g9P7StructSP8StructS2y 199; OPT: store i32 1, 200; OPT: store i32 4, 201; Remove a load and propagate the value from store. 202; OPT: ret i32 1 203 %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %S, i64 0, i32 1 204 store i32 1, i32* %f32, align 4, !tbaa !15 205 %f321 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %S2, i64 0, i32 1 206 store i32 4, i32* %f321, align 4, !tbaa !18 207 ret i32 1 208} 209 210; uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) { 211; S->f32 = 1; 212; S2->f16 = 4; 213; return S->f32; 214; } 215; 216define i32 @_Z3g10P7StructSP8StructS2y(%struct.StructS* nocapture %S, %struct.StructS2* nocapture %S2, i64 %count) { 217entry: 218; CHECK-LABEL: _Z3g10P7StructSP8StructS2y 219; CHECK: NoAlias: store i16 4, {{.*}} <-> store i32 1, 220; OPT-LABEL: _Z3g10P7StructSP8StructS2y 221; OPT: store i32 1, 222; OPT: store i16 4, 223; Remove a load and propagate the value from store. 224; OPT: ret i32 1 225 %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %S, i64 0, i32 1 226 store i32 1, i32* %f32, align 4, !tbaa !15 227 %f16 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %S2, i64 0, i32 0 228 store i16 4, i16* %f16, align 4, !tbaa !20 229 ret i32 1 230} 231 232; uint32_t g11(StructC *C, StructD *D, uint64_t count) { 233; C->b.a.f32 = 1; 234; D->b.a.f32 = 4; 235; return C->b.a.f32; 236; } 237; 238define i32 @_Z3g11P7StructCP7StructDy(%struct.StructC* nocapture %C, %struct.StructD* nocapture %D, i64 %count) { 239entry: 240; CHECK-LABEL: _Z3g11P7StructCP7StructDy 241; CHECK: NoAlias: store i32 4, {{.*}} <-> store i32 1, 242; OPT-LABEL: _Z3g11P7StructCP7StructDy 243; OPT: store i32 1, 244; OPT: store i32 4, 245; Remove a load and propagate the value from store. 246; OPT: ret i32 1 247 %f32 = getelementptr inbounds %struct.StructC, %struct.StructC* %C, i64 0, i32 1, i32 1, i32 1 248 store i32 1, i32* %f32, align 4, !tbaa !21 249 %f323 = getelementptr inbounds %struct.StructD, %struct.StructD* %D, i64 0, i32 1, i32 1, i32 1 250 store i32 4, i32* %f323, align 4, !tbaa !23 251 ret i32 1 252} 253 254; uint32_t g12(StructC *C, StructD *D, uint64_t count) { 255; StructB *b1 = &(C->b); 256; StructB *b2 = &(D->b); 257; // b1, b2 have different context. 258; b1->a.f32 = 1; 259; b2->a.f32 = 4; 260; return b1->a.f32; 261; } 262; 263define i32 @_Z3g12P7StructCP7StructDy(%struct.StructC* nocapture %C, %struct.StructD* nocapture %D, i64 %count) { 264entry: 265; CHECK-LABEL: _Z3g12P7StructCP7StructDy 266; CHECK: MayAlias: store i32 4, {{.*}} <-> store i32 1, 267; OPT-LABEL: _Z3g12P7StructCP7StructDy 268; OPT: store i32 1, 269; OPT: store i32 4, 270; OPT: %[[RET:.*]] = load i32, 271; OPT: ret i32 %[[RET]] 272 %f32 = getelementptr inbounds %struct.StructC, %struct.StructC* %C, i64 0, i32 1, i32 1, i32 1 273 store i32 1, i32* %f32, align 4, !tbaa !10 274 %f325 = getelementptr inbounds %struct.StructD, %struct.StructD* %D, i64 0, i32 1, i32 1, i32 1 275 store i32 4, i32* %f325, align 4, !tbaa !10 276 %0 = load i32, i32* %f32, align 4, !tbaa !10 277 ret i32 %0 278} 279 280!2 = !{!3, !3, i64 0, i64 4} 281!3 = !{!4, i64 4, !"int"} 282!4 = !{!5, i64 1, !"omnipotent char"} 283!5 = !{!"Simple C++ TBAA"} 284!6 = !{!7, !3, i64 4, i64 4} 285!7 = !{!4, i64 16, !"_ZTS7StructA", !8, i64 0, i64 2, !3, i64 4, i64 4, !8, i64 8, i64 2, !3, i64 12, i64 4} 286!8 = !{!4, i64 2, !"short"} 287!9 = !{!7, !8, i64 0, i64 2} 288!10 = !{!11, !3, i64 8, i64 4} 289!11 = !{!4, i64 24, !"_ZTS7StructB", !8, i64 0, i64 2, !7, i64 4, i64 16, !3, i64 20, i64 4} 290!12 = !{!11, !8, i64 4, i64 2} 291!13 = !{!11, !3, i64 20, i64 4} 292!14 = !{!11, !3, i64 16, i64 4} 293!15 = !{!16, !3, i64 4, i64 4} 294!16 = !{!4, i64 8, !"_ZTS7StructS", !8, i64 0, i64 2, !3, i64 4, i64 4} 295!17 = !{!16, !8, i64 0, i64 2} 296!18 = !{!19, !3, i64 4, i64 4} 297!19 = !{!4, i64 8, !"_ZTS8StructS2", !8, i64 0, i64 2, !3, i64 4, i64 4} 298!20 = !{!19, !8, i64 0, i64 2} 299!21 = !{!22, !3, i64 12, i64 4} 300!22 = !{!4, i64 32, !"_ZTS7StructC", !8, i64 0, i64 2, !11, i64 4, i64 24, !3, i64 28, i64 4} 301!23 = !{!24, !3, i64 12, i64 4} 302!24 = !{!4, i64 36, !"_ZTS7StructD", !8, i64 0, i64 2, !11, i64 4, i64 24, !3, i64 28, i64 4, !4, i64 32, i64 1} 303!25 = !{!26, !4, i64 1, i64 1} 304!26 = !{!4, i64 3, !"_ZTS4five", !4, i64 0, i64 1, !3, i64 1, i64 4, !4, i64 1, i64 1, !4, i64 2, i64 1} 305!27 = !{!28, !4, i64 4, i64 1} 306!28 = !{!4, i64 6, !"_ZTS3six", !4, i64 0, i64 1, !3, i64 4, i64 4, !4, i64 4, i64 1, !4, i64 5, i64 1} 307