Skip to content

Commit c9c8024

Browse files
committed
[TBAA] Extend pointer TBAA to pointers of non-builtin types.
Extend the logic added in 123c036 (#76612) to support pointers to non-builtin types by using the mangled name of the canonical type.
1 parent 8ae39c8 commit c9c8024

File tree

3 files changed

+61
-23
lines changed

3 files changed

+61
-23
lines changed

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,21 +221,27 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
221221
PtrDepth++;
222222
Ty = Ty->getPointeeType().getTypePtr();
223223
} while (Ty->isPointerType());
224-
// TODO: Implement C++'s type "similarity" and consider dis-"similar"
225-
// pointers distinct for non-builtin types.
224+
225+
SmallString<256> TyName;
226226
if (isa<BuiltinType>(Ty)) {
227227
llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
228228
StringRef Name =
229229
cast<llvm::MDString>(
230230
ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
231231
->getString();
232+
TyName = Name;
233+
} else if (!isa<VariableArrayType>(Ty)) {
234+
// For non-builtin types use the mangled name of the canonical type.
235+
llvm::raw_svector_ostream TyOut(TyName);
236+
Context.createMangleContext()->mangleCanonicalTypeName(QualType(Ty, 0),
237+
TyOut);
238+
}
239+
232240
SmallString<256> OutName("p");
233241
OutName += std::to_string(PtrDepth);
234242
OutName += " ";
235-
OutName += Name;
243+
OutName += TyName;
236244
return createScalarTypeNode(OutName, AnyPtr, Size);
237-
}
238-
return AnyPtr;
239245
}
240246

241247
// Accesses to arrays are accesses to objects of their element types.

clang/test/CodeGen/tbaa-pointers.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,12 @@ void p2struct(struct S1 **ptr) {
116116
// COMMON-LABEL: define void @p2struct(
117117
// COMMON-SAME: ptr noundef [[PTR:%.+]])
118118
// COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
119-
// ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]]
119+
// ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG:!.+]]
120120
// DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
121-
// COMMON-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
122-
// COMMON-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
121+
// ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2S1_TAG]]
122+
// DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
123+
// ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG:!.+]]
124+
// DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
123125
// COMMON-NEXT: ret void
124126
//
125127
*ptr = 0;
@@ -129,9 +131,10 @@ void p2struct_const(struct S1 const **ptr) {
129131
// COMMON-LABEL: define void @p2struct_const(
130132
// COMMON-SAME: ptr noundef [[PTR:%.+]])
131133
// COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
132-
// COMMON-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
134+
// COMMON-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR:!.+]]
133135
// COMMON-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
134-
// COMMON-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
136+
// ENABLED-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_TAG]]
137+
// DEFAULT-NEXT: store ptr null, ptr [[BASE]], align 8, !tbaa [[ANYPTR]]
135138
// COMMON-NEXT: ret void
136139
//
137140
*ptr = 0;
@@ -145,10 +148,14 @@ void p2struct2(struct S2 *ptr) {
145148
// COMMON-LABEL: define void @p2struct2(
146149
// COMMON-SAME: ptr noundef [[PTR:%.+]])
147150
// COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
148-
// COMMON-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
149-
// COMMON-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
150-
// COMMON-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0
151-
// COMMON-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]]
151+
// ENABLED-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG:!.+]]
152+
// ENABLED-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P1S2_TAG]]
153+
// ENABLED-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0
154+
// ENABLED-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]]
155+
// DEFAULT-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
156+
// DEFAULT-NEXT: [[BASE:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
157+
// DEFAULT-NEXT: [[S:%.+]] = getelementptr inbounds nuw %struct.S2, ptr [[BASE]], i32 0, i32 0
158+
// DEFAULT-NEXT: store ptr null, ptr [[S]], align 8, !tbaa [[S2_S_TAG:!.+]]
152159
// COMMON-NEXT: ret void
153160
ptr->s = 0;
154161
}
@@ -171,5 +178,14 @@ void p2struct2(struct S2 *ptr) {
171178
// ENABLED: [[P2CHAR]] = !{!"p2 omnipotent char", [[ANY_POINTER]], i64 0}
172179
// ENABLED: [[P1CHAR_0]] = !{[[P1CHAR:!.+]], [[P1CHAR]], i64 0}
173180
// ENABLED: [[P1CHAR]] = !{!"p1 omnipotent char", [[ANY_POINTER]], i64 0}
174-
// COMMON: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[ANY_POINTER]], i64 0}
175-
// COMMON: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0}
181+
// ENABLED: [[P2S1_TAG]] = !{[[P2S1:!.+]], [[P2S1]], i64 0}
182+
// ENABLED: [[P2S1]] = !{!"p2 _ZTS2S1", [[ANY_POINTER]], i64 0}
183+
// ENABLED: [[P1S1_TAG:!.+]] = !{[[P1S1:!.+]], [[P1S1]], i64 0}
184+
// ENABLED: [[P1S1]] = !{!"p1 _ZTS2S1", [[ANY_POINTER]], i64 0}
185+
// ENABLED: [[P1S2_TAG]] = !{[[P1S2:!.+]], [[P1S2]], i64 0}
186+
// ENABLED: [[P1S2]] = !{!"p1 _ZTS2S2", [[ANY_POINTER]], i64 0}
187+
188+
// ENABLED: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[P1S1]], i64 0}
189+
// ENABLED: [[S2_TY]] = !{!"S2", [[P1S1]], i64 0}
190+
// DEFAULT: [[S2_S_TAG]] = !{[[S2_TY:!.+]], [[ANY_POINTER]], i64 0}
191+
// DEFAULT: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0}

clang/test/CodeGen/tbaa-reference.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,OLD-PATH
2-
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes -pointer-tbaa %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,OLD-PATH
2+
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes -pointer-tbaa %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,OLD-PATH-POINTER
33
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=CHECK,NEW-PATH
4-
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -pointer-tbaa -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=CHECK,NEW-PATH
4+
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -pointer-tbaa -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=CHECK,NEW-PATH-POINTER
55
//
66
// Check that we generate correct TBAA information for reference accesses.
77

@@ -16,13 +16,13 @@ struct B {
1616
B::B(S &s) : s(s) {
1717
// CHECK-LABEL: _ZN1BC2ER1S
1818
// Check initialization of the reference parameter.
19-
// CHECK: store ptr {{.*}}, ptr {{.*}}, !tbaa [[TAG_pointer:!.*]]
19+
// CHECK: store ptr {{.*}}, ptr %s.addr, align 8, !tbaa [[TAG_S_PTR:!.*]]
2020

2121
// Check loading of the reference parameter.
22-
// CHECK: load ptr, ptr {{.*}}, !tbaa [[TAG_pointer]]
22+
// CHECK: load ptr, ptr {{.*}}, !tbaa [[TAG_S_PTR:!.*]]
2323

2424
// Check initialization of the reference member.
25-
// CHECK: store ptr {{.*}}, ptr {{.*}}, !tbaa [[TAG_pointer]]
25+
// CHECK: store ptr {{.*}}, ptr {{.*}}, !tbaa [[TAG_S_PTR]]
2626
}
2727

2828
S &B::get() {
@@ -32,16 +32,32 @@ S &B::get() {
3232
return s;
3333
}
3434

35-
// OLD-PATH-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0}
35+
// OLD-PATH-DAG: [[TAG_S_PTR]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0}
3636
// OLD-PATH-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0}
3737
//
3838
// OLD-PATH-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_pointer]], i64 0}
3939
// OLD-PATH-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0}
4040
// OLD-PATH-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}
4141

42-
// NEW-PATH-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0, i64 8}
42+
// OLD-PATH-POINTER-DAG: [[TAG_S_PTR]] = !{[[TYPE_S_PTR:!.*]], [[TYPE_S_PTR]], i64 0}
43+
// OLD-PATH-POINTER-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_S_PTR:!.*]], i64 0}
44+
//
45+
// OLD-PATH-POINTER-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_S_PTR:!.*]], i64 0}
46+
// OLD-PATH-POINTER-DAG: [[TYPE_pointer:!.*]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0}
47+
// OLD-PATH-POINTER-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}
48+
// OLD-PATH-POINTER-DAG: [[TYPE_S_PTR]] = !{!"p1 _ZTS1S", [[TYPE_pointer]], i64 0}
49+
50+
// NEW-PATH-DAG: [[TAG_S_PTR]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0, i64 8}
4351
// NEW-PATH-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0, i64 8}
4452
//
4553
// NEW-PATH-DAG: [[TYPE_B]] = !{[[TYPE_char:!.*]], i64 8, !"_ZTS1B", [[TYPE_pointer]], i64 0, i64 8}
4654
// NEW-PATH-DAG: [[TYPE_pointer]] = !{[[TYPE_char:!.*]], i64 8, !"any pointer"}
4755
// NEW-PATH-DAG: [[TYPE_char]] = !{{{!.*}}, i64 1, !"omnipotent char"}
56+
57+
// NEW-PATH-POINTER-DAG: [[TAG_S_PTR]] = !{[[TYPE_S_PTR:!.*]], [[TYPE_S_PTR]], i64 0, i64 8}
58+
// NEW-PATH-POINTER-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_S_PTR]], i64 0, i64 8}
59+
//
60+
// NEW-PATH-POINTER-DAG: [[TYPE_B]] = !{[[TYPE_char:!.*]], i64 8, !"_ZTS1B", [[TYPE_S_PTR]], i64 0, i64 8}
61+
// NEW-PATH-POINTER-DAG: [[TYPE_S_PTR]] = !{[[TYPE_pointer:!.+]], i64 8, !"p1 _ZTS1S"}
62+
// NEW-PATH-POINTER-DAG: [[TYPE_pointer]] = !{[[TYPE_char:!.*]], i64 8, !"any pointer"}
63+
// NEW-PATH-POINTER-DAG: [[TYPE_char]] = !{{{!.*}}, i64 1, !"omnipotent char"}

0 commit comments

Comments
 (0)