diff options
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGen/tbaa-union.cpp | 100 | ||||
-rw-r--r-- | clang/test/CodeGen/union-tbaa1.c | 14 |
2 files changed, 108 insertions, 6 deletions
diff --git a/clang/test/CodeGen/tbaa-union.cpp b/clang/test/CodeGen/tbaa-union.cpp new file mode 100644 index 00000000000..066d7c9e9ff --- /dev/null +++ b/clang/test/CodeGen/tbaa-union.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for accesses to union +// members. + +struct X { + int a, b; + int arr[3]; + int c, d; +}; + +union U { + int i; + X x; + int j; +}; + +struct S { + U u, v; +}; + +union N { + int i; + S s; + int j; +}; + +struct R { + N n, m; +}; + +int f1(U *p) { +// CHECK-LABEL: _Z2f1P1U +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_U_j:!.*]] + return p->j; +} + +int f2(S *p) { +// CHECK-LABEL: _Z2f2P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_u_i:!.*]] + return p->u.i; +} + +int f3(S *p) { +// CHECK-LABEL: _Z2f3P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_v_j:!.*]] + return p->v.j; +} + +int f4(S *p) { +// CHECK-LABEL: _Z2f4P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_u_x_b:!.*]] + return p->u.x.b; +} + +int f5(S *p) { +// CHECK-LABEL: _Z2f5P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_v_x_b:!.*]] + return p->v.x.b; +} + +int f6(S *p) { +// CHECK-LABEL: _Z2f6P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_u_x_arr:!.*]] + return p->u.x.arr[1]; +} + +int f7(S *p) { +// CHECK-LABEL: _Z2f7P1S +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_S_v_x_arr:!.*]] + return p->v.x.arr[1]; +} + +int f8(N *p) { +// CHECK-LABEL: _Z2f8P1N +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_N_s_v_x_c:!.*]] + return p->s.v.x.c; +} + +int f9(R *p) { +// CHECK-LABEL: _Z2f9P1R +// CHECK: load i32, i32* {{.*}}, !tbaa [[TAG_R_m_s_v_x_c:!.*]] + return p->m.s.v.x.c; +} + +// CHECK-DAG: [[TAG_U_j]] = !{[[TYPE_U:!.*]], [[TYPE_union_member:!.*]], i64 0} +// CHECK-DAG: [[TAG_S_u_i]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TAG_S_u_x_b]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TAG_S_u_x_arr]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TAG_S_v_j]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 28} +// CHECK-DAG: [[TAG_S_v_x_b]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 28} +// CHECK-DAG: [[TAG_S_v_x_arr]] = !{[[TYPE_S:!.*]], [[TYPE_union_member]], i64 28} +// CHECK-DAG: [[TAG_N_s_v_x_c]] = !{[[TYPE_N:!.*]], [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TAG_R_m_s_v_x_c]] = !{[[TYPE_R:!.*]], [[TYPE_union_member]], i64 56} +// CHECK-DAG: [[TYPE_U]] = !{!"_ZTS1U", [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TYPE_S]] = !{!"_ZTS1S", [[TYPE_U]], i64 0, [[TYPE_U]], i64 28} +// CHECK-DAG: [[TYPE_N]] = !{!"_ZTS1N", [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TYPE_R]] = !{!"_ZTS1R", [[TYPE_N]], i64 0, [[TYPE_N]], i64 56} +// CHECK-DAG: [[TYPE_union_member]] = !{!"union member", [[TYPE_char:!.*]], i64 0} +// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{.*}}, i64 0} diff --git a/clang/test/CodeGen/union-tbaa1.c b/clang/test/CodeGen/union-tbaa1.c index 07f5fcfeb42..7a6d2ccd00d 100644 --- a/clang/test/CodeGen/union-tbaa1.c +++ b/clang/test/CodeGen/union-tbaa1.c @@ -15,30 +15,32 @@ void fred(unsigned Num, int Vec[2], int *Index, int Arr[4][2]) { // But no tbaa for the two stores: // CHECK: %uw[[UW1:[0-9]*]] = getelementptr // CHECK: store{{.*}}%uw[[UW1]] -// CHECK: tbaa ![[OCPATH:[0-9]+]] +// CHECK: tbaa [[TAG_vect32_union_member:![0-9]+]] // There will be a load after the store, and it will use tbaa. Make sure // the check-not above doesn't find it: // CHECK: load Tmp[*Index][0].uw = Arr[*Index][0] * Num; // CHECK: %uw[[UW2:[0-9]*]] = getelementptr // CHECK: store{{.*}}%uw[[UW2]] -// CHECK: tbaa ![[OCPATH]] +// CHECK: tbaa [[TAG_vect32_union_member]] Tmp[*Index][1].uw = Arr[*Index][1] * Num; // Same here, don't generate tbaa for the loads: // CHECK: %uh[[UH1:[0-9]*]] = bitcast %union.vect32 // CHECK: %arrayidx[[AX1:[0-9]*]] = getelementptr{{.*}}%uh[[UH1]] // CHECK: load i16, i16* %arrayidx[[AX1]] -// CHECK: tbaa ![[OCPATH]] +// CHECK: tbaa [[TAG_vect32_union_member]] // CHECK: store Vec[0] = Tmp[*Index][0].uh[1]; // CHECK: %uh[[UH2:[0-9]*]] = bitcast %union.vect32 // CHECK: %arrayidx[[AX2:[0-9]*]] = getelementptr{{.*}}%uh[[UH2]] // CHECK: load i16, i16* %arrayidx[[AX2]] -// CHECK: tbaa ![[OCPATH]] +// CHECK: tbaa [[TAG_vect32_union_member]] // CHECK: store Vec[1] = Tmp[*Index][1].uh[1]; bar(Tmp); } -// CHECK-DAG: ![[CHAR:[0-9]+]] = !{!"omnipotent char" -// CHECK-DAG: ![[OCPATH]] = !{![[CHAR]], ![[CHAR]], i64 0} +// CHECK-DAG: [[TAG_vect32_union_member]] = !{[[TYPE_vect32:!.*]], [[TYPE_union_member:!.*]], i64 0} +// CHECK-DAG: [[TYPE_vect32]] = !{!"", [[TYPE_union_member]], i64 0} +// CHECK-DAG: [[TYPE_union_member]] = !{!"union member", [[TYPE_char:!.*]], i64 0} +// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{.*}}} |