-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[TBAA] Don't emit pointer tbaa for unnamed structs or unions. #116596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Florian Hahn (fhahn) ChangesFor unnamed structs or unions, C's compatible types rule applies. Two compatible types in different compilation units can have different mangled names, meaning the metadata emitted below would incorrectly mark them as no-alias. Use AnyPtr for such types in both C and C++, as C and C++ types may be visible when doing LTO. Full diff: https://github.com/llvm/llvm-project/pull/116596.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index c31579e8323174..95d9f893a2c7d1 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -230,6 +230,15 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
->getString();
TyName = Name;
} else {
+ // For unnamed structs or unions C's compatible types rule applies. Two
+ // compatible types in different compilation units can have different
+ // mangled names, meaning the metadata emitted below would incorrectly
+ // mark them as no-alias. Use AnyPtr for such types in both C and C++, as
+ // C and C++ types may be visible when doing LTO.
+ const auto *RT = Ty->getAs<RecordType>();
+ if (RT && !RT->getDecl()->getDeclName())
+ return AnyPtr;
+
// For non-builtin types use the mangled name of the canonical type.
llvm::raw_svector_ostream TyOut(TyName);
MangleCtx->mangleCanonicalTypeName(QualType(Ty, 0), TyOut);
diff --git a/clang/test/CodeGen/tbaa-pointers.c b/clang/test/CodeGen/tbaa-pointers.c
index 9417a0e2f09e8c..068459f4dce118 100644
--- a/clang/test/CodeGen/tbaa-pointers.c
+++ b/clang/test/CodeGen/tbaa-pointers.c
@@ -190,8 +190,6 @@ typedef struct {
int i1;
} TypedefS;
-// FIXME: The !tbaa tag for unnamed structs doesn't account for compatible
-// types in C.
void unamed_struct_typedef(TypedefS *ptr) {
// COMMON-LABEL: define void @unamed_struct_typedef(
// COMMON-SAME: ptr noundef [[PTRA:%.+]])
@@ -238,5 +236,4 @@ void unamed_struct_typedef(TypedefS *ptr) {
// DEFAULT: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0}
// COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0}
// COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0}
-// ENABLED: [[P1TYPEDEF]] = !{[[P1TYPEDEF_TY:!.+]], [[P1TYPEDEF_TY]], i64 0}
-// ENABLED: [[P1TYPEDEF_TY]] = !{!"p1 _ZTS8TypedefS", [[ANY_POINTER]], i64 0}
+// ENABLED: [[P1TYPEDEF]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0}
|
// compatible types in different compilation units can have different | ||
// mangled names, meaning the metadata emitted below would incorrectly | ||
// mark them as no-alias. Use AnyPtr for such types in both C and C++, as | ||
// C and C++ types may be visible when doing LTO. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like this to note that
- using AnyPtr is over-conservative here, and we could make this summarize the members as per the C compatibility rule in the future and
- this also covers anonymous structs and unions, which have a different compatibility rule, but it doesn't matter because you can never have a pointer to an anonymous struct or union.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, added the clarifications as suggested!
87b0688
to
ddd22cf
Compare
For unnamed structs or unions, C's compatible types rule applies. Two compatible types in different compilation units can have different mangled names, meaning the metadata emitted below would incorrectly mark them as no-alias. Use AnyPtr for such types in both C and C++, as C and C++ types may be visible when doing LTO.
ddd22cf
to
fe01d7e
Compare
clang/lib/CodeGen/CodeGenTBAA.cpp
Outdated
// compatibility rule, but it doesn't matter because you can never have a | ||
// pointer to an anonymous struct or union. | ||
const auto *RT = Ty->getAs<RecordType>(); | ||
if (RT && !RT->getDecl()->getDeclName()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This getAs<>
is now redundant with the isRecordType()
above; please do the getAs<>
above and test RT
there, and then you can assume you have a record here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
Support for more precise TBAA metadata has been added a while ago (behind the -fpointer-tbaa flag). The more precise TBAA metadata allows treating accesses of different pointer types as no-alias. This helps to remove more redundant loads and stores in a number of workloads. Some highlights on the impact across llvm-test-suite's MultiSource, SPEC2006 & SPEC2017 include: * +2% more NoAlias results for memory access * +4% more loops vectorized * +3% more stores removed by DSE. This closes a relatively big gap to GCC, which has been supporting disambiguating based on pointer types for a long time. (https://clang.godbolt.org/z/K7Wbhrz4q) Pointer-TBAA support for pointers to builtin types has been added in llvm#76612. Support for user-defined types has been added in llvm#110569. There are 2 pending PRs with bug fixes for special cases uncovered during some of my testing: * llvm#116991 * llvm#116596
Support for more precise TBAA metadata has been added a while ago (behind the -fpointer-tbaa flag). The more precise TBAA metadata allows treating accesses of different pointer types as no-alias. This helps to remove more redundant loads and stores in a number of workloads. Some highlights on the impact across llvm-test-suite's MultiSource, SPEC2006 & SPEC2017 include: * +2% more NoAlias results for memory access * +4% more loops vectorized * +3% more stores removed by DSE. This closes a relatively big gap to GCC, which has been supporting disambiguating based on pointer types for a long time. (https://clang.godbolt.org/z/K7Wbhrz4q) Pointer-TBAA support for pointers to builtin types has been added in llvm#76612. Support for user-defined types has been added in llvm#110569. There are 2 pending PRs with bug fixes for special cases uncovered during some of my testing: * llvm#116991 * llvm#116596
Support for more precise TBAA metadata has been added a while ago (behind the -fpointer-tbaa flag). The more precise TBAA metadata allows treating accesses of different pointer types as no-alias. This helps to remove more redundant loads and stores in a number of workloads. Some highlights on the impact across llvm-test-suite's MultiSource, SPEC2006 & SPEC2017 include: * +2% more NoAlias results for memory access * +4% more loops vectorized * +3% more stores removed by DSE. This closes a relatively big gap to GCC, which has been supporting disambiguating based on pointer types for a long time. (https://clang.godbolt.org/z/K7Wbhrz4q) Pointer-TBAA support for pointers to builtin types has been added in llvm#76612. Support for user-defined types has been added in llvm#110569. There are 2 pending PRs with bug fixes for special cases uncovered during some of my testing: * llvm#116991 * llvm#116596
Support for more precise TBAA metadata has been added a while ago (behind the -fpointer-tbaa flag). The more precise TBAA metadata allows treating accesses of different pointer types as no-alias. This helps to remove more redundant loads and stores in a number of workloads. Some highlights on the impact across llvm-test-suite's MultiSource, SPEC2006 & SPEC2017 include: * +2% more NoAlias results for memory accesses * +3% more stores removed by DSE, * +4% more loops vectorized. This closes a relatively big gap to GCC, which has been supporting disambiguating based on pointer types for a long time. (https://clang.godbolt.org/z/K7Wbhrz4q) Pointer-TBAA support for pointers to builtin types has been added in #76612. Support for user-defined types has been added in #110569. There are 2 recent PRs with bug fixes for special cases uncovered during testing: * #116991 * #116596 PR: #117244
…16596) For unnamed structs or unions, C's compatible types rule applies. Two compatible types in different compilation units can have different mangled names, meaning the metadata emitted below would incorrectly mark them as no-alias. Use AnyPtr for such types in both C and C++, as C and C++ types may be visible when doing LTO. PR: llvm#116596 (cherry picked from commit 41a0c66)
For unnamed structs or unions, C's compatible types rule applies. Two compatible types in different compilation units can have different mangled names, meaning the metadata emitted below would incorrectly mark them as no-alias. Use AnyPtr for such types in both C and C++, as C and C++ types may be visible when doing LTO.