[CodeGen] Fix generation of TBAA tags for may-alias accesses

This patch fixes creating TBAA access descriptors for
may_alias-marked access types. Currently, for such types we
generate ordinary descriptors with char as its access type. The
patch changes this to produce proper may-alias descriptors.

Differential Revision: https://reviews.llvm.org/D42366

llvm-svn: 325575
This commit is contained in:
Ivan A. Kosarev 2018-02-20 12:33:04 +00:00
parent 3ebf760a92
commit 124a2187ad
4 changed files with 63 additions and 31 deletions

View File

@ -602,13 +602,9 @@ llvm::MDNode *CodeGenModule::getTBAATypeInfo(QualType QTy) {
}
TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) {
// Pointee values may have incomplete types, but they shall never be
// dereferenced.
if (AccessType->isIncompleteType())
return TBAAAccessInfo::getIncompleteInfo();
uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
return TBAAAccessInfo(getTBAATypeInfo(AccessType), Size);
if (!TBAA)
return TBAAAccessInfo();
return TBAA->getAccessInfo(AccessType);
}
TBAAAccessInfo

View File

@ -215,6 +215,19 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
return MetadataCache[Ty] = TypeNode;
}
TBAAAccessInfo CodeGenTBAA::getAccessInfo(QualType AccessType) {
// Pointee values may have incomplete types, but they shall never be
// dereferenced.
if (AccessType->isIncompleteType())
return TBAAAccessInfo::getIncompleteInfo();
if (TypeHasMayAlias(AccessType))
return TBAAAccessInfo::getMayAliasInfo();
uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
return TBAAAccessInfo(getTypeInfo(AccessType), Size);
}
TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
llvm::DataLayout DL(&Module);
unsigned Size = DL.getPointerTypeSize(VTablePtrType);

View File

@ -177,6 +177,10 @@ public:
/// given type.
llvm::MDNode *getTypeInfo(QualType QTy);
/// getAccessInfo - Get TBAA information that describes an access to
/// an object of the given type.
TBAAAccessInfo getAccessInfo(QualType AccessType);
/// getVTablePtrAccessInfo - Get the TBAA information that describes an
/// access to a virtual table pointer.
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType);

View File

@ -1,18 +1,24 @@
// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -no-struct-path-tbaa -disable-llvm-passes -o - %s | FileCheck %s
// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=PATH
// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \
// RUN: -no-struct-path-tbaa -disable-llvm-passes -o - %s | \
// RUN: FileCheck %s -check-prefixes=CHECK,SCALAR
// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \
// RUN: -disable-llvm-passes -o - %s | \
// RUN: FileCheck %s -check-prefixes=CHECK,OLD-PATH
// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \
// RUN: -new-struct-path-tbaa -disable-llvm-passes -o - %s | \
// RUN: FileCheck %s -check-prefixes=CHECK,NEW-PATH
// Types with the may_alias attribute should be considered equivalent
// to char for aliasing.
typedef int __attribute__((may_alias)) aliasing_int;
void test0(aliasing_int *ai, int *i)
{
// CHECK: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]]
// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]]
void test0(aliasing_int *ai, int *i) {
// CHECK-LABEL: test0
// CHECK: store i32 0, {{.*}}, !tbaa [[TAG_alias_int:!.*]]
*ai = 0;
// CHECK: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]]
// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]]
// CHECK: store i32 1, {{.*}}, !tbaa [[TAG_int:!.*]]
*i = 1;
}
@ -20,23 +26,36 @@ void test0(aliasing_int *ai, int *i)
struct Test1 { int x; };
struct Test1MA { int x; } __attribute__((may_alias));
void test1(struct Test1MA *p1, struct Test1 *p2) {
// CHECK: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]]
// PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]]
// CHECK-LABEL: test1
// CHECK: store i32 2, {{.*}}, !tbaa [[TAG_alias_test1_x:!.*]]
p1->x = 2;
// CHECK: store i32 3, i32* {{%.*}}, !tbaa [[TAG_INT]]
// PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]]
// CHECK: store i32 3, {{.*}}, !tbaa [[TAG_test1_x:!.*]]
p2->x = 3;
}
// CHECK: !"any pointer", [[TYPE_CHAR:!.*]],
// CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", [[TAG_CXX_TBAA:!.*]],
// CHECK: [[TAG_CXX_TBAA]] = !{!"Simple C/C++ TBAA"}
// CHECK: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0}
// CHECK: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
// CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
// PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !{{.*}}
// PATH: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0}
// PATH: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
// PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
// PATH: [[TAG_test1_x]] = !{[[TYPE_test1:!.*]], [[TYPE_INT]], i64 0}
// PATH: [[TYPE_test1]] = !{!"Test1", [[TYPE_INT]], i64 0}
// SCALAR-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"}
// SCALAR-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0}
// SCALAR-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0}
// SCALAR-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0}
// SCALAR-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0}
// SCALAR-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0}
// SCALAR-DAG: [[TAG_test1_x]] = !{[[TYPE_int]], [[TYPE_int]], i64 0}
// OLD-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"}
// OLD-PATH-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0}
// OLD-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0}
// OLD-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0}
// OLD-PATH-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0}
// OLD-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0}
// OLD-PATH-DAG: [[TYPE_test1:!.*]] = !{!"Test1", [[TYPE_int]], i64 0}
// OLD-PATH-DAG: [[TAG_test1_x]] = !{[[TYPE_test1]], [[TYPE_int]], i64 0}
// NEW-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"}
// NEW-PATH-DAG: [[TYPE_char:!.*]] = !{[[ROOT]], i64 1, !"omnipotent char"}
// NEW-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0}
// NEW-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0}
// NEW-PATH-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"}
// NEW-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4}
// NEW-PATH-DAG: [[TYPE_test1:!.*]] = !{[[TYPE_char]], i64 4, !"Test1", [[TYPE_int]], i64 0, i64 4}
// NEW-PATH-DAG: [[TAG_test1_x]] = !{[[TYPE_test1]], [[TYPE_int]], i64 0, i64 4}