https://github.com/brunodf-snps updated 
https://github.com/llvm/llvm-project/pull/137719

>From d63c8fe4fcc8e89933bf3c1cc176941b0b9094fa Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Mon, 28 Apr 2025 14:12:00 +0200
Subject: [PATCH 1/6] [clang][CodeGen] Make tbaa-array test more robust

Avoid unintentional matches against extra load/stores in the unoptimized
LLVM IR.
---
 clang/test/CodeGen/tbaa-array.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/test/CodeGen/tbaa-array.cpp 
b/clang/test/CodeGen/tbaa-array.cpp
index 4a6576e2eeb7f..ce34e7d586e3e 100644
--- a/clang/test/CodeGen/tbaa-array.cpp
+++ b/clang/test/CodeGen/tbaa-array.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
+// RUN: %clang_cc1 -triple x86_64-linux -O1 %s \
 // RUN:     -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
+// RUN: %clang_cc1 -triple x86_64-linux -O1 %s \
 // RUN:     -new-struct-path-tbaa -emit-llvm -o - | \
 // RUN:     FileCheck -check-prefix=CHECK-NEW %s
 //
@@ -45,7 +45,6 @@ int bar3(C *c, int j) {
 // 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}

>From bba5ee5ed17af062f91604d3185d733df944df67 Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Tue, 29 Apr 2025 00:07:02 +0200
Subject: [PATCH 2/6] [CodeGen] Add TBAA struct path info for array members

This enables the LLVM optimizer to view accesses to distinct struct
members as independent, also for array members. For example, the
following two stores no longer alias:

    struct S { int a[10]; int b; };
    void test(S *p, int i) {
      p->a[i] = ...;
      p->b = ...;
    }

Array members were already added to TBAA struct type nodes in commit
57493e2. Here, we extend a path tag for an array subscript expression.
---
 clang/lib/CodeGen/CGExpr.cpp      | 27 ++++++++++++++++++++++++++-
 clang/test/CodeGen/tbaa-array.cpp | 21 +++++++++++++++++++--
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index bba7d1e805f3f..c95a54fcebba9 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4503,7 +4503,32 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
         E->getType(), !getLangOpts().PointerOverflowDefined, SignedIndices,
         E->getExprLoc(), &arrayType, E->getBase());
     EltBaseInfo = ArrayLV.getBaseInfo();
-    EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
+    if (!CGM.getCodeGenOpts().NewStructPathTBAA) {
+      // Since CodeGenTBAA::getTypeInfoHelper only handles array types for
+      // new struct path TBAA, we must a use a plain access.
+      EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
+    } else if (ArrayLV.getTBAAInfo().isMayAlias()) {
+      EltTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
+    } else if (ArrayLV.getTBAAInfo().isIncomplete()) {
+      EltTBAAInfo = CGM.getTBAAAccessInfo(E->getType());
+    } else {
+      // Extend struct path from base lvalue, similar to EmitLValueForField.
+      // If no base type has been assigned for the array access, then try to
+      // generate one.
+      EltTBAAInfo = ArrayLV.getTBAAInfo();
+      if (!EltTBAAInfo.BaseType) {
+        EltTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(ArrayLV.getType());
+        assert(!EltTBAAInfo.Offset &&
+               "Nonzero offset for an access with no base type!");
+      }
+      // The index into the array is a runtime value. We use the same struct
+      // path for all array elements (that of the element at index 0). So we
+      // set the access type and size, but do not have to adjust
+      // EltTBAAInfo.Offset.
+      EltTBAAInfo.AccessType = CGM.getTBAATypeInfo(E->getType());
+      EltTBAAInfo.Size =
+          getContext().getTypeSizeInChars(E->getType()).getQuantity();
+    }
   } else {
     // The base must be a pointer; emit it with an estimate of its alignment.
     Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
diff --git a/clang/test/CodeGen/tbaa-array.cpp 
b/clang/test/CodeGen/tbaa-array.cpp
index ce34e7d586e3e..7cda1dd8d5bf7 100644
--- a/clang/test/CodeGen/tbaa-array.cpp
+++ b/clang/test/CodeGen/tbaa-array.cpp
@@ -10,6 +10,8 @@
 struct A { int i; };
 struct B { A a[1]; };
 struct C { int i; int x[3]; };
+struct D { int n; int arr[]; }; // flexible array member
+extern int AA[];                // incomplete array type
 
 int foo(B *b) {
 // CHECK-LABEL: _Z3fooP1B
@@ -28,16 +30,30 @@ int bar(C *c) {
 
 int bar2(C *c) {
 // CHECK-NEW-LABEL: _Z4bar2P1C
-// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_x:!.*]]
   return c->x[2];
 }
 
 int bar3(C *c, int j) {
 // CHECK-NEW-LABEL: _Z4bar3P1Ci
-// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_x]]
   return c->x[j];
 }
 
+int bar4(D *d) {
+// CHECK-NEW-LABEL: _Z4bar4P1D
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+    return d->arr[d->n];
+}
+
+int bar5(int j) {
+// CHECK-NEW-LABEL: _Z4bar5i
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
+    return AA[2] + AA[j];
+}
+
 // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
 // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
 // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
@@ -49,3 +65,4 @@ int bar3(C *c, int j) {
 // 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}
+// CHECK-NEW-DAG: [[TAG_C_x]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 4, i64 
4}

>From 0258b0dec28312f4c2b5c79562b17959656d51b7 Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Sun, 18 May 2025 22:52:23 +0200
Subject: [PATCH 3/6] CGExpr: tweak generation of EltTBAAInfo

---
 clang/lib/CodeGen/CGExpr.cpp | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c95a54fcebba9..6893d57224f25 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4510,17 +4510,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
     } else if (ArrayLV.getTBAAInfo().isMayAlias()) {
       EltTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
     } else if (ArrayLV.getTBAAInfo().isIncomplete()) {
+      // The array element is complete, even if the array is not.
       EltTBAAInfo = CGM.getTBAAAccessInfo(E->getType());
     } else {
       // Extend struct path from base lvalue, similar to EmitLValueForField.
-      // If no base type has been assigned for the array access, then try to
-      // generate one.
       EltTBAAInfo = ArrayLV.getTBAAInfo();
-      if (!EltTBAAInfo.BaseType) {
-        EltTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(ArrayLV.getType());
-        assert(!EltTBAAInfo.Offset &&
-               "Nonzero offset for an access with no base type!");
-      }
+      // If no base type has been assigned for the array access, there is no
+      // point trying to generate one, since an array is not a valid base type.
+      //
       // The index into the array is a runtime value. We use the same struct
       // path for all array elements (that of the element at index 0). So we
       // set the access type and size, but do not have to adjust

>From 52cb263643ef37abf80e14bc9de933e3f3e6fa5a Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Tue, 20 May 2025 23:36:24 +0200
Subject: [PATCH 4/6] CGExpr: rework code comment

---
 clang/lib/CodeGen/CGExpr.cpp | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6893d57224f25..06be69ab0a609 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4513,15 +4513,21 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
       // The array element is complete, even if the array is not.
       EltTBAAInfo = CGM.getTBAAAccessInfo(E->getType());
     } else {
-      // Extend struct path from base lvalue, similar to EmitLValueForField.
+      // The TBAA access info from the array (base) lvalue is ordinary. We will
+      // adapt it to create access info for the element.
       EltTBAAInfo = ArrayLV.getTBAAInfo();
-      // If no base type has been assigned for the array access, there is no
-      // point trying to generate one, since an array is not a valid base type.
-      //
-      // The index into the array is a runtime value. We use the same struct
-      // path for all array elements (that of the element at index 0). So we
-      // set the access type and size, but do not have to adjust
-      // EltTBAAInfo.Offset.
+
+      // We retain the TBAA struct path (BaseType and Offset members) from the
+      // array. In the TBAA representation, we map any array access to the
+      // element at index 0, as the index is generally a runtime value. This
+      // element has the same offset in the base type as the array itself.
+      // If the array lvalue had no base type, there is no point trying to
+      // generate one, since an array itself is not a valid base type.
+
+      // The access size must be updated to the size of an individual element.
+      // We also reset the access type using the original element type: in case
+      // of type decoration on the element type they may have been lost when
+      // the array type was canonicalized.
       EltTBAAInfo.AccessType = CGM.getTBAATypeInfo(E->getType());
       EltTBAAInfo.Size =
           getContext().getTypeSizeInChars(E->getType()).getQuantity();

>From 1a40063bc73ee468cb6c8634505232b6f2d833ec Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Tue, 27 May 2025 10:43:45 +0200
Subject: [PATCH 5/6] CodeGenTBAA/CGExpr: fix cases with may_alias arrays

---
 clang/lib/CodeGen/CGExpr.cpp      |  7 ++-----
 clang/lib/CodeGen/CodeGenTBAA.cpp |  7 +++++++
 clang/test/CodeGen/tbaa-array.cpp | 25 +++++++++++++++++++++++--
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 06be69ab0a609..86d20baf7a170 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4524,11 +4524,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const 
ArraySubscriptExpr *E,
       // If the array lvalue had no base type, there is no point trying to
       // generate one, since an array itself is not a valid base type.
 
-      // The access size must be updated to the size of an individual element.
-      // We also reset the access type using the original element type: in case
-      // of type decoration on the element type they may have been lost when
-      // the array type was canonicalized.
-      EltTBAAInfo.AccessType = CGM.getTBAATypeInfo(E->getType());
+      // We also retain the access type from the base lvalue, but the access
+      // size must be updated to the size of an individual element.
       EltTBAAInfo.Size =
           getContext().getTypeSizeInChars(E->getType()).getQuantity();
     }
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 818b6dabaa144..a02a009158d12 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -130,6 +130,13 @@ static bool TypeHasMayAlias(QualType QTy) {
       return true;
     QTy = TT->desugar();
   }
+
+  // Also consider an array type as may_alias when its element type (at
+  // any level) is marked as such.
+  if (auto *ArrayTy = QTy->getAsArrayTypeUnsafe())
+    if (TypeHasMayAlias(ArrayTy->getElementType()))
+      return true;
+
   return false;
 }
 
diff --git a/clang/test/CodeGen/tbaa-array.cpp 
b/clang/test/CodeGen/tbaa-array.cpp
index 7cda1dd8d5bf7..aac86e778981c 100644
--- a/clang/test/CodeGen/tbaa-array.cpp
+++ b/clang/test/CodeGen/tbaa-array.cpp
@@ -13,6 +13,12 @@ struct C { int i; int x[3]; };
 struct D { int n; int arr[]; }; // flexible array member
 extern int AA[];                // incomplete array type
 
+typedef int __attribute__((may_alias)) aliasing_int;
+typedef int __attribute__((may_alias)) aliasing_array[10];
+struct E {
+    aliasing_int x[4]; aliasing_array y;
+};
+
 int foo(B *b) {
 // CHECK-LABEL: _Z3fooP1B
 // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
@@ -54,6 +60,18 @@ int bar5(int j) {
     return AA[2] + AA[j];
 }
 
+int bar6(E *e, int j) {
+// CHECK-NEW-LABEL: _Z4bar6P1Ei
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_E_x:!.*]]
+    return e->x[j];
+}
+
+int bar7(E *e, int j) {
+// CHECK-NEW-LABEL: _Z4bar7P1Ei
+// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_E_y:!.*]]
+    return e->y[j];
+}
+
 // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
 // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
 // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
@@ -64,5 +82,8 @@ int bar5(int j) {
 // 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}
-// CHECK-NEW-DAG: [[TAG_C_x]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 4, i64 
4}
+// CHECK-NEW-DAG: [[TAG_C_i]] = !{[[TYPE_C]], [[TYPE_int]], i64 0, i64 4}
+// CHECK-NEW-DAG: [[TAG_C_x]] = !{[[TYPE_C]], [[TYPE_int]], i64 4, i64 4}
+// CHECK-NEW-DAG: [[TYPE_E:!.*]] = !{[[TYPE_char]], i64 56, !"_ZTS1E", 
[[TYPE_char]], i64 0, i64 16, [[TYPE_char]], i64 16, i64 40}
+// CHECK-NEW-DAG: [[TAG_E_x]] = !{[[TYPE_E]], [[TYPE_char]], i64 0, i64 4}
+// CHECK-NEW-DAG: [[TAG_E_y]] = !{[[TYPE_E]], [[TYPE_char]], i64 16, i64 4}

>From e8d27035f240c0ff62dcd0b52d9a0483c61aaeee Mon Sep 17 00:00:00 2001
From: Bruno De Fraine <brun...@synopsys.com>
Date: Tue, 27 May 2025 13:16:15 +0200
Subject: [PATCH 6/6] tbaa-array test: fix formatting

---
 clang/test/CodeGen/tbaa-array.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/clang/test/CodeGen/tbaa-array.cpp 
b/clang/test/CodeGen/tbaa-array.cpp
index aac86e778981c..35e525cfa67ca 100644
--- a/clang/test/CodeGen/tbaa-array.cpp
+++ b/clang/test/CodeGen/tbaa-array.cpp
@@ -15,9 +15,7 @@ extern int AA[];                // incomplete array type
 
 typedef int __attribute__((may_alias)) aliasing_int;
 typedef int __attribute__((may_alias)) aliasing_array[10];
-struct E {
-    aliasing_int x[4]; aliasing_array y;
-};
+struct E { aliasing_int x[4]; aliasing_array y; };
 
 int foo(B *b) {
 // CHECK-LABEL: _Z3fooP1B

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to