瀏覽代碼

[CodeGen] Represent array members in new-format TBAA type descriptors

Now that in the new TBAA format we allow access types to be of
any object types, including aggregate ones, it becomes critical
to specify types of all sub-objects such aggregates comprise as
their members. In order to meet this requirement, this patch
enables generation of field descriptors for members of array
types.

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


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321352 91177308-0d34-0410-b5e6-96231b3b80d8
Ivan A. Kosarev 7 年之前
父節點
當前提交
4e09f68a2c
共有 2 個文件被更改,包括 38 次插入0 次删除
  1. 4 0
      lib/CodeGen/CodeGenTBAA.cpp
  2. 34 0
      test/CodeGen/tbaa-array.cpp

+ 4 - 0
lib/CodeGen/CodeGenTBAA.cpp

@@ -161,6 +161,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
   if (Ty->isPointerType() || Ty->isReferenceType())
   if (Ty->isPointerType() || Ty->isReferenceType())
     return createScalarTypeNode("any pointer", getChar(), Size);
     return createScalarTypeNode("any pointer", getChar(), Size);
 
 
+  // Accesses to arrays are accesses to objects of their element types.
+  if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
+    return getTypeInfo(cast<ArrayType>(Ty)->getElementType());
+
   // Enum types are distinct types. In C++ they have "underlying types",
   // Enum types are distinct types. In C++ they have "underlying types",
   // however they aren't related for TBAA.
   // however they aren't related for TBAA.
   if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
   if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {

+ 34 - 0
test/CodeGen/tbaa-array.cpp

@@ -1,18 +1,52 @@
 // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
 // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
 // RUN:     -emit-llvm -o - | FileCheck %s
 // RUN:     -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
+// RUN:     -new-struct-path-tbaa -emit-llvm -o - | \
+// RUN:     FileCheck -check-prefix=CHECK-NEW %s
 //
 //
 // Check that we generate correct TBAA information for accesses to array
 // Check that we generate correct TBAA information for accesses to array
 // elements.
 // elements.
 
 
 struct A { int i; };
 struct A { int i; };
 struct B { A a[1]; };
 struct B { A a[1]; };
+struct C { int i; int x[3]; };
 
 
 int foo(B *b) {
 int foo(B *b) {
 // CHECK-LABEL: _Z3fooP1B
 // CHECK-LABEL: _Z3fooP1B
 // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
 // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
+// CHECK-NEW-LABEL: _Z3fooP1B
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
   return b->a->i;
   return b->a->i;
 }
 }
 
 
+// Check that members of array types are represented correctly.
+int bar(C *c) {
+// CHECK-NEW-LABEL: _Z3barP1C
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]]
+  return c->i;
+}
+
+int bar2(C *c) {
+// CHECK-NEW-LABEL: _Z4bar2P1C
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+  return c->x[2];
+}
+
+int bar3(C *c, int j) {
+// CHECK-NEW-LABEL: _Z4bar3P1Ci
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+  return c->x[j];
+}
+
 // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
 // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
 // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
 // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
 // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
 // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
+
+// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"}
+// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"}
+// CHECK-NEW-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4}
+// CHECK-NEW-DAG: [[TYPE_pointer:!.*]] = !{[[TYPE_char]], i64 8, !"any pointer"}
+// CHECK-NEW-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4}
+// CHECK-NEW-DAG: [[TAG_A_i]] = !{[[TYPE_A]], [[TYPE_int]], i64 0, i64 4}
+// CHECK-NEW-DAG: [[TYPE_C:!.*]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12}
+// CHECK-NEW-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 4}