Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -602,13 +602,9 @@ } 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 Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -177,6 +177,10 @@ /// 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); Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -215,6 +215,19 @@ 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); Index: test/CodeGen/may-alias.c =================================================================== --- test/CodeGen/may-alias.c +++ test/CodeGen/may-alias.c @@ -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 @@ 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}