[clang] [TBAA] Emit "omnipotent char" for intrinsics with type cast (PR #107793)

via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 8 18:15:08 PDT 2024


https://github.com/huhu233 created https://github.com/llvm/llvm-project/pull/107793

For the case,
```
  long long res2[SIZE];
  svst1(pa, (long *)&res2[0], v2);
  /* use res2[i] */
```
svst1 is emitted with TBAA metadata for "long", but other users of "res2" use "long long", which is a strict aliasing violation and may cause incorrect optimization like https://github.com/llvm/llvm-project/issues/97783. The root cause is we explictly cast the type of res2 when calling svst1, and the compiler emits an improper type. This patch fixes the case by emitting "omnipotent char" for intrinsics with type cast.

>From 433a80915de87098093302b57f8554bbf33fdeca Mon Sep 17 00:00:00 2001
From: zhangtiehu <zhangtiehu at huawei.com>
Date: Tue, 3 Sep 2024 14:43:50 +0800
Subject: [PATCH 1/2] [TBAA] Precommit a test for tbaa enhancement

---
 clang/test/CodeGen/tbaa-sve-store-acle.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 clang/test/CodeGen/tbaa-sve-store-acle.c

diff --git a/clang/test/CodeGen/tbaa-sve-store-acle.c b/clang/test/CodeGen/tbaa-sve-store-acle.c
new file mode 100644
index 00000000000000..3a7c49c27e41ca
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-sve-store-acle.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -O1  %s \
+// RUN:     -emit-llvm -o - | FileCheck %s -check-prefix=TBAA
+#include <arm_sve.h>
+
+// TBAA:    store <vscale x 2 x i64>
+// TBAA:    !tbaa ![[TBAA6:[0-9]+]]
+long long sveStoreWithTypeCast(int *datas) {
+  long long res2[16];
+  svbool_t pa = svptrue_b32();
+  svint32_t v1 = svld1(pa, &datas[0]);
+  svint64_t v2 = svunpklo(v1);
+  svst1(pa, (long *)&res2[0], v2);
+  return res2[0] + res2[1];
+}
+
+// TBAA: ![[CHAR:[0-9]+]] = !{!"omnipotent char",
+// TBAA: ![[TBAA6:[0-9]+]] = !{![[LONG:.+]], ![[LONG]], i64 0}
+// TBAA: ![[LONG:[0-9]+]] = !{!"long", ![[CHAR]], i64 0}

>From dbe0528ad1599a0ed89929647bec5f7b7118e1b3 Mon Sep 17 00:00:00 2001
From: zhangtiehu <zhangtiehu at huawei.com>
Date: Mon, 2 Sep 2024 17:45:23 +0800
Subject: [PATCH 2/2] [TBAA] Emit "omnipotent char" for intrinsics with type
 cast

For the case,

  long long res2[SIZE];
  svst1(pa, (long *)&res2[0], v2);
  /* use res2[i] */

svst1 is emitted with TBAA metadata for "long", but other users of
"res2" use "long long", which is a strict aliasing violation and may
cause incorrect optimization like #97783. The root cause is we explictly
cast the type of res2 when calling svst1, and the compiler emits an
improper type. This patch fixes the case by emitting "omnipotent char"
for intrinsics with type cast.
---
 clang/lib/CodeGen/CGBuiltin.cpp          | 10 ++++++++++
 clang/lib/CodeGen/CodeGenModule.cpp      |  4 ++++
 clang/lib/CodeGen/CodeGenModule.h        |  2 ++
 clang/lib/CodeGen/CodeGenTBAA.cpp        |  5 +++++
 clang/lib/CodeGen/CodeGenTBAA.h          |  2 ++
 clang/test/CodeGen/tbaa-sve-store-acle.c |  3 +--
 6 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index da7a1a55da5313..27fd5ce976bec5 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -10155,6 +10155,11 @@ Value *CodeGenFunction::EmitSVEMaskedLoad(const CallExpr *E,
   auto *Load =
       cast<llvm::Instruction>(Builder.CreateCall(F, {Predicate, BasePtr}));
   auto TBAAInfo = CGM.getTBAAAccessInfo(LangPTy->getPointeeType());
+  if (auto *CastE = dyn_cast<CastExpr>(E->getArg(1))) {
+    CastKind CK = CastE->getCastKind();
+    if (CK == CK_BitCast)
+      TBAAInfo = CGM.genConservativeTBAA(LangPTy->getPointeeType());
+  }
   CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
 
   if (IsQuadLoad)
@@ -10207,6 +10212,11 @@ Value *CodeGenFunction::EmitSVEMaskedStore(const CallExpr *E,
   auto *Store =
       cast<llvm::Instruction>(Builder.CreateCall(F, {Val, Predicate, BasePtr}));
   auto TBAAInfo = CGM.getTBAAAccessInfo(LangPTy->getPointeeType());
+  if (auto *CastE = dyn_cast<CastExpr>(E->getArg(1))) {
+    CastKind CK = CastE->getCastKind();
+    if (CK == CK_BitCast)
+      TBAAInfo = CGM.genConservativeTBAA(LangPTy->getPointeeType());
+  }
   CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
   return Store;
 }
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index df4c13c9ad97aa..7c25591d08a92a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1499,6 +1499,10 @@ TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) {
   return TBAA->getAccessInfo(AccessType);
 }
 
+TBAAAccessInfo CodeGenModule::genConservativeTBAA(QualType AccessType) {
+  return TBAA->genConservativeTBAA(AccessType);
+}
+
 TBAAAccessInfo
 CodeGenModule::getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
   if (!TBAA)
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index c58bb88035ca8a..2c30429850907e 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -811,6 +811,8 @@ class CodeGenModule : public CodeGenTypeCache {
   /// an object of the given type.
   TBAAAccessInfo getTBAAAccessInfo(QualType AccessType);
 
+  TBAAAccessInfo genConservativeTBAA(QualType AccessType);
+
   /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an
   /// access to a virtual table pointer.
   TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType);
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 5b3393ec150e44..be285ba0dbff2a 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -306,6 +306,11 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
   return MetadataCache[Ty] = TypeNode;
 }
 
+TBAAAccessInfo CodeGenTBAA::genConservativeTBAA(QualType AccessType) {
+  uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
+  return TBAAAccessInfo(getChar(), Size);
+}
+
 TBAAAccessInfo CodeGenTBAA::getAccessInfo(QualType AccessType) {
   // Pointee values may have incomplete types, but they shall never be
   // dereferenced.
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index ba74a39a4d25ee..de89783bc13e17 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -213,6 +213,8 @@ class CodeGenTBAA {
   /// purpose of memory transfer calls.
   TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
                                                 TBAAAccessInfo SrcInfo);
+
+  TBAAAccessInfo genConservativeTBAA(QualType AccessType);
 };
 
 }  // end namespace CodeGen
diff --git a/clang/test/CodeGen/tbaa-sve-store-acle.c b/clang/test/CodeGen/tbaa-sve-store-acle.c
index 3a7c49c27e41ca..e9078ecb4370ad 100644
--- a/clang/test/CodeGen/tbaa-sve-store-acle.c
+++ b/clang/test/CodeGen/tbaa-sve-store-acle.c
@@ -14,5 +14,4 @@ long long sveStoreWithTypeCast(int *datas) {
 }
 
 // TBAA: ![[CHAR:[0-9]+]] = !{!"omnipotent char",
-// TBAA: ![[TBAA6:[0-9]+]] = !{![[LONG:.+]], ![[LONG]], i64 0}
-// TBAA: ![[LONG:[0-9]+]] = !{!"long", ![[CHAR]], i64 0}
+// TBAA: ![[TBAA6:[0-9]+]] = !{![[CHAR]], ![[CHAR]], i64 0}



More information about the cfe-commits mailing list