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