[clang] decb874 - [TBAA] Only emit pointer tbaa metedata for record types. (#116991)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 21 12:01:10 PST 2024
Author: Florian Hahn
Date: 2024-11-21T20:01:06Z
New Revision: decb87452d8e3b93b21ab9e4c3dd03d85cbebfa5
URL: https://github.com/llvm/llvm-project/commit/decb87452d8e3b93b21ab9e4c3dd03d85cbebfa5
DIFF: https://github.com/llvm/llvm-project/commit/decb87452d8e3b93b21ab9e4c3dd03d85cbebfa5.diff
LOG: [TBAA] Only emit pointer tbaa metedata for record types. (#116991)
Be conservative if the type isn't a record type. Handling other types
may
require stripping const-qualifiers inside the type, e.g.
MemberPointerType.
Also look through array types same as through pointer types, to not
pessimize
arrays of pointers.
Without this, we assign different tags to the accesses for p an q in the
second test in cwg158.
PR: https://github.com/llvm/llvm-project/pull/116991
Added:
Modified:
clang/lib/CodeGen/CodeGenTBAA.cpp
clang/test/CXX/drs/cwg158.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index c31579e8323174..4bcb541156bd23 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -205,14 +205,27 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size);
if (!CodeGenOpts.PointerTBAA)
return AnyPtr;
- // Compute the depth of the pointer and generate a tag of the form "p<depth>
- // <base type tag>".
+ // C++ [basic.lval]p11 permits objects to accessed through an l-value of
+ // similar type. Two types are similar under C++ [conv.qual]p2 if the
+ // decomposition of the types into pointers, member pointers, and arrays has
+ // the same structure when ignoring cv-qualifiers at each level of the
+ // decomposition. Meanwhile, C makes T(*)[] and T(*)[N] compatible, which
+ // would really complicate any attempt to distinguish pointers to arrays by
+ // their bounds. It's simpler, and much easier to explain to users, to
+ // simply treat all pointers to arrays as pointers to their element type for
+ // aliasing purposes. So when creating a TBAA tag for a pointer type, we
+ // recursively ignore both qualifiers and array types when decomposing the
+ // pointee type. The only meaningful remaining structure is the number of
+ // pointer types we encountered along the way, so we just produce the tag
+ // "p<depth> <base type tag>". If we do find a member pointer type, for now
+ // we just conservatively bail out with AnyPtr (below) rather than trying to
+ // create a tag that honors the similar-type rules while still
+ // distinguishing
diff erent kinds of member pointer.
unsigned PtrDepth = 0;
do {
PtrDepth++;
- Ty = Ty->getPointeeType().getTypePtr();
+ Ty = Ty->getPointeeType()->getBaseElementTypeUnsafe();
} while (Ty->isPointerType());
- Ty = Context.getBaseElementType(QualType(Ty, 0)).getTypePtr();
assert(!isa<VariableArrayType>(Ty));
// When the underlying type is a builtin type, we compute the pointee type
// string recursively, which is implicitly more forgiving than the standards
@@ -230,6 +243,12 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
->getString();
TyName = Name;
} else {
+ // Be conservative if the type isn't a RecordType. We are specifically
+ // required to do this for member pointers until we implement the
+ // similar-types rule.
+ if (!Ty->isRecordType())
+ 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/CXX/drs/cwg158.cpp b/clang/test/CXX/drs/cwg158.cpp
index 9301c790297e9d..2a744382647773 100644
--- a/clang/test/CXX/drs/cwg158.cpp
+++ b/clang/test/CXX/drs/cwg158.cpp
@@ -1,12 +1,14 @@
-// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++98 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++11 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++14 %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck --check-prefixes=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-linux -std=c++1z %s -O3 -pointer-tbaa -disable-llvm-passes -pedantic-errors -emit-llvm -o - | FileCheck --check-prefixes=CHECK,POINTER-TBAA %s
// cwg158: yes
// CHECK-LABEL: define {{.*}} @_Z1f
const int *f(const int * const *p, int **q) {
+ // CHECK: load ptr, ptr %p.addr
// CHECK: load ptr, {{.*}}, !tbaa ![[INTPTR_TBAA:[^,]*]]
const int *x = *p;
// CHECK: store ptr null, {{.*}}, !tbaa ![[INTPTR_TBAA]]
@@ -18,6 +20,7 @@ struct A {};
// CHECK-LABEL: define {{.*}} @_Z1g
const int *(A::*const *g(const int *(A::* const **p)[3], int *(A::***q)[3]))[3] {
+ // CHECK: load ptr, ptr %p.addr
// CHECK: load ptr, {{.*}}, !tbaa ![[MEMPTR_TBAA:[^,]*]]
const int *(A::*const *x)[3] = *p;
// CHECK: store ptr null, {{.*}}, !tbaa ![[MEMPTR_TBAA]]
@@ -25,3 +28,16 @@ const int *(A::*const *g(const int *(A::* const **p)[3], int *(A::***q)[3]))[3]
return x;
}
+// CHECK-LABEL: define {{.*}} @_Z1h
+const int * h(const int * (*p)[10], int *(*q)[9]) {
+ // CHECK: load ptr, ptr %p.addr, align 8, !tbaa [[PTRARRAY_TBAA:!.+]]
+ const int * x = *p[0];
+
+ // CHECK: load ptr, ptr %q.addr, align 8, !tbaa [[PTRARRAY_TBAA]]
+ *q[0] = 0;
+ return x;
+}
+
+// POINTER-TBAA: [[PTRARRAY_TBAA]] = !{[[PTRARRAY_TY:!.+]], [[PTRARRAY_TY]], i64 0}
+// POINTER-TBAA: [[PTRARRAY_TY]] = !{!"p2 int", [[ANYPTR:!.+]], i64 0}
+// POINTER-TBAA: [[ANYPTR]] = !{!"any pointer"
More information about the cfe-commits
mailing list