fhahn updated this revision to Diff 469329.
fhahn added a comment.

Rebased on current main

In D122573#3630767 <https://reviews.llvm.org/D122573#3630767>, @rui.zhang wrote:

> I like the direction where this change is leading to and hope there is some 
> way to land it incrementally. Since BuiltinType has the above mentioned 
> concern on `void *`, how about we focus on `RecordType` pointers as a first 
> step instead? Are there any pitfalls if we distinguish `RecordType` pointers 
> by depth?

An initial restriction like that sounds reasonable to me. @jcranmer-intel 
@efriedma @rjmccall WDYT?

I also updated the type sanitizer patches and posted 
https://discourse.llvm.org/t/reviving-typesanitizer-a-sanitizer-to-catch-type-based-aliasing-violations/66092
 to discuss ways to move forward with the sanitizer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122573/new/

https://reviews.llvm.org/D122573

Files:
  clang/lib/CodeGen/CodeGenTBAA.cpp
  clang/test/CodeGen/tbaa-pointers.c

Index: clang/test/CodeGen/tbaa-pointers.c
===================================================================
--- clang/test/CodeGen/tbaa-pointers.c
+++ clang/test/CodeGen/tbaa-pointers.c
@@ -1,12 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
 
-void p2unsigned(unsigned **ptr) {
+void p2unsigned(unsigned** ptr) {
   // CHECK-LABEL: define void @p2unsigned(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:  %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0:!.+]]
-  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:  store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0:!.+]]
+  // CHECK-NEXT:  [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:  store ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0:!.+]]
   // CHECK-NEXT:  ret void
   //
   *ptr = 0;
@@ -16,9 +16,9 @@
   // CHECK-LABEL: define void @p2unsigned_volatile(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:   store volatile ptr null, ptr [[BASE]], align 8, !tbaa [[P1INT_0]]
   // CHECK-NEXT:   ret void
   //
   *ptr = 0;
@@ -28,10 +28,10 @@
   // CHECK-LABEL: define void @p3int(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P3INT_0:!.+]]
+  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P3INT_0]]
+  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P2INT_0]]
+  // CHECK-NEXT:   store ptr null, ptr [[BASE_1]], align 8, !tbaa [[P1INT_0]]
   // CHECK-NEXT:   ret void
   //
   **ptr = 0;
@@ -41,11 +41,11 @@
   // CHECK-LABEL: define void @p4char(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0:!.+]]
+  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0]]
+  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0:!.+]]
+  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0:!.+]]
+  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0:!.+]]
   // CHECK-NEXT:   ret void
   //
   ***ptr = 0;
@@ -55,11 +55,11 @@
   // CHECK-LABEL: define void @p4char_const1(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0]]
+  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0]]
+  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]]
+  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]]
+  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]]
   // CHECK-NEXT:   ret void
   //
   ***ptr = 0;
@@ -69,11 +69,11 @@
   // CHECK-LABEL: define void @p4char_const2(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0]]
+  // CHECK-NEXT:   [[BASE_0:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P4CHAR_0]]
+  // CHECK-NEXT:   [[BASE_1:%.+]] = load ptr, ptr [[BASE_0]], align 8, !tbaa [[P3CHAR_0]]
+  // CHECK-NEXT:   [[BASE_2:%.+]] = load ptr, ptr [[BASE_1]], align 8, !tbaa [[P2CHAR_0]]
+  // CHECK-NEXT:   store ptr null, ptr [[BASE_2]], align 8, !tbaa [[P1CHAR_0]]
   // CHECK-NEXT:   ret void
   //
   ***ptr = 0;
@@ -88,16 +88,28 @@
   // CHECK-LABEL: define void @p2struct(ptr noundef %ptr)
   // CHECK-NEXT: entry:
   // CHECK-NEXT:   %ptr.addr = alloca ptr, align 8
-  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]]
-  // CHECK-NEXT:   store ptr null, ptr [[BASE]], align 8, !tbaa [[ANY_POINTER_0]]
+  // CHECK-NEXT:   store ptr %ptr, ptr %ptr.addr, align 8, !tbaa [[P2S1_0:!.+]]
+  // CHECK-NEXT:   [[BASE:%.+]] = load ptr, ptr %ptr.addr, align 8, !tbaa [[P2S1_0]]
+  // CHECK-NEXT:   store ptr null, ptr [[BASE]], align 8, !tbaa [[P1S1_:!.+]]
   // CHECK-NEXT:   ret void
   //
   *ptr = 0;
 }
 
-// CHECK: [[ANY_POINTER_0]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0}
+// CHECK: [[P2INT_0]] = !{[[P2INT:!.+]], [[P2INT]], i64 0}
+// CHECK: [[P2INT]] = !{!"p2 int", [[ANY_POINTER:!.+]], i64 0}
 // CHECK: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0}
 // CHECK: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0}
 // CHECK: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"}
-//
+// CHECK: [[P1INT_0]] = !{[[P1INT:!.+]], [[P1INT]], i64 0}
+// CHECK: [[P1INT]] = !{!"p1 int", [[ANY_POINTER]], i64 0}
+// CHECK: [[P3INT_0]] = !{[[P3INT:!.+]], [[P3INT]], i64 0}
+// CHECK: [[P3INT]] = !{!"p3 int", [[ANY_POINTER]], i64 0}
+// CHECK: [[P4CHAR_0]] = !{[[P4CHAR:!.+]], [[P4CHAR]], i64 0}
+// CHECK: [[P4CHAR]] = !{!"p4 omnipotent char", [[ANY_POINTER]], i64 0}
+// CHECK: [[P3CHAR_0]] = !{[[P3CHAR:!.+]], [[P3CHAR]], i64 0}
+// CHECK: [[P3CHAR]] = !{!"p3 omnipotent char", [[ANY_POINTER]], i64 0}
+// CHECK: [[P2CHAR_0]] = !{[[P2CHAR:!.+]], [[P2CHAR]], i64 0}
+// CHECK: [[P2CHAR]] = !{!"p2 omnipotent char", [[ANY_POINTER]], i64 0}
+// CHECK: [[P1CHAR_0]] = !{[[P1CHAR:!.+]], [[P1CHAR]], i64 0}
+// CHECK: [[P1CHAR]] = !{!"p1 omnipotent char", [[ANY_POINTER]], i64 0}
Index: clang/lib/CodeGen/CodeGenTBAA.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenTBAA.cpp
+++ clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -184,10 +184,31 @@
     return getChar();
 
   // Handle pointers and references.
-  // TODO: Implement C++'s type "similarity" and consider dis-"similar"
-  // pointers distinct.
-  if (Ty->isPointerType() || Ty->isReferenceType())
-    return createScalarTypeNode("any pointer", getChar(), Size);
+  if (Ty->isPointerType() || Ty->isReferenceType()) {
+    llvm::MDNode *AnyPtr = createScalarTypeNode("any pointer", getChar(), Size);
+    // Compute the depth of the pointer and generate a tag of the form "p<depth>
+    // <base type tag>".
+    unsigned PtrDepth = 0;
+    do {
+      PtrDepth++;
+      Ty = Ty->getPointeeType().getTypePtr();
+    } while (Ty->isPointerType() || Ty->isReferenceType());
+    // TODO: Implement C++'s type "similarity" and consider dis-"similar"
+    // pointers distinct for non-builtin types.
+    if (isa<BuiltinType>(Ty)) {
+      llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
+      StringRef Name =
+          cast<llvm::MDString>(
+              ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
+              ->getString();
+      SmallString<256> OutName("p");
+      OutName += std::to_string(PtrDepth);
+      OutName += " ";
+      OutName += Name;
+      return createScalarTypeNode(OutName, AnyPtr, Size);
+    }
+    return AnyPtr;
+  }
 
   // Accesses to arrays are accesses to objects of their element types.
   if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D122573: [TBAA] Emit ... Florian Hahn via Phabricator via cfe-commits

Reply via email to