[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:40 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (huhu233)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/107793.diff


6 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+10) 
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+4) 
- (modified) clang/lib/CodeGen/CodeGenModule.h (+2) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+5) 
- (modified) clang/lib/CodeGen/CodeGenTBAA.h (+2) 
- (added) clang/test/CodeGen/tbaa-sve-store-acle.c (+17) 


``````````diff
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
new file mode 100644
index 00000000000000..e9078ecb4370ad
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-sve-store-acle.c
@@ -0,0 +1,17 @@
+// 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]+]] = !{![[CHAR]], ![[CHAR]], i64 0}

``````````

</details>


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


More information about the cfe-commits mailing list