https://github.com/HendrikHuebner created 
https://github.com/llvm/llvm-project/pull/169226

This PR implements the basic handling for emitting TBAA attributes during 
lowering.

TODO: Tests

From 89e04a20bebc64c967adae0eea5c7ff14497d559 Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Fri, 21 Nov 2025 02:39:40 +0100
Subject: [PATCH] [CIR] Upstream initial TBAA implementation

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |   8 +-
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |   8 +
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  23 ++-
 clang/lib/CIR/CodeGen/CIRGenBuilder.h         |   4 +-
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          |   5 +-
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp      |   1 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |   9 +-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  70 +++++++
 clang/lib/CIR/CodeGen/CIRGenModule.h          |  50 +++++
 clang/lib/CIR/CodeGen/CIRGenTBAA.cpp          |  65 ++++++
 clang/lib/CIR/CodeGen/CIRGenTBAA.h            | 188 ++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenValue.h           |  32 ++-
 clang/lib/CIR/CodeGen/CMakeLists.txt          |   1 +
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       |   6 +
 clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp    |   2 +-
 15 files changed, 445 insertions(+), 27 deletions(-)
 create mode 100644 clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
 create mode 100644 clang/lib/CIR/CodeGen/CIRGenTBAA.h

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index be9965ae3101f..371f046c25ba0 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
                          bool isVolatile = false, uint64_t alignment = 0) {
     mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
     return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
-                               alignmentAttr, cir::MemOrderAttr{});
+                               alignmentAttr, cir::MemOrderAttr{}, 
/*tbaa=*/mlir::ArrayAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -321,14 +321,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
   /// Create a copy with inferred length.
   cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
                          bool isVolatile = false) {
-    return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
+    return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile, 
/*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value 
dst,
                            bool isVolatile = false,
                            mlir::IntegerAttr align = {},
                            cir::MemOrderAttr order = {}) {
-    return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, 
order);
+    return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, 
order, /*tbaa=*/mlir::ArrayAttr{});
   }
 
   [[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
@@ -353,7 +353,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
     return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
                                /*isVolatile=*/false, alignmentAttr,
-                               /*mem_order=*/{});
+                               /*mem_order=*/{}, /*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 12bc9cf7b5b04..5dbfe9334c867 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -447,6 +447,14 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", 
[TypedAttrInterface]> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// TBAAAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
+  let summary = "CIR dialect TBAA base attribute";
+}
+
 
//===----------------------------------------------------------------------===//
 // GlobalViewAttr
 
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a19c4f951fff9..40710783c97c0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -586,7 +586,10 @@ def CIR_LoadOp : CIR_Op<"load", [
                        UnitAttr:$isDeref,
                        UnitAttr:$is_volatile,
                        OptionalAttr<I64Attr>:$alignment,
-                       OptionalAttr<CIR_MemOrder>:$mem_order);
+                       OptionalAttr<CIR_MemOrder>:$mem_order,
+                       OptionalAttr<ArrayAttr>:$tbaa
+  );
+
   let results = (outs CIR_AnyType:$result);
 
   let assemblyFormat = [{
@@ -595,6 +598,7 @@ def CIR_LoadOp : CIR_Op<"load", [
     (`align` `(` $alignment^ `)`)?
     (`atomic` `(` $mem_order^ `)`)?
     $addr `:` qualified(type($addr)) `,` type($result) attr-dict
+    (`tbaa` `(` $tbaa^ `)`)?
   }];
 
   // FIXME: add verifier.
@@ -638,13 +642,16 @@ def CIR_StoreOp : CIR_Op<"store", [
                            [MemWrite]>:$addr,
                        UnitAttr:$is_volatile,
                        OptionalAttr<I64Attr>:$alignment,
-                       OptionalAttr<CIR_MemOrder>:$mem_order);
+                       OptionalAttr<CIR_MemOrder>:$mem_order,
+                       OptionalAttr<ArrayAttr>:$tbaa
+  );
 
   let assemblyFormat = [{
     (`volatile` $is_volatile^)?
     (`align` `(` $alignment^ `)`)?
     (`atomic` `(` $mem_order^ `)`)?
     $value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
+    (`tbaa` `(` $tbaa^ `)`)?
   }];
 
   // FIXME: add verifier.
@@ -2979,12 +2986,16 @@ def CIR_CopyOp : CIR_Op<"copy",[
   let arguments = (ins
       Arg<CIR_PointerType, "", [MemWrite]>:$dst,
       Arg<CIR_PointerType, "", [MemRead]>:$src,
-      UnitAttr:$is_volatile
+      UnitAttr:$is_volatile,
+      OptionalAttr<ArrayAttr>:$tbaa
   );
 
-  let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
-                        attr-dict `:` qualified(type($dst))
+  let assemblyFormat = [{
+    $src `to` $dst (`volatile` $is_volatile^)?
+    attr-dict `:` qualified(type($dst))
+    (`tbaa` `(` $tbaa^ `)`)?
   }];
+
   let hasVerifier = 1;
 
   let extraClassDeclaration = [{
@@ -2994,7 +3005,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
     /// Returns the number of bytes to be copied.
     unsigned getLength(const mlir::DataLayout &dt) {
       return dt.getTypeSize(getType().getPointee());
-    }    
+    }
   }];
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 85b38120169fd..98cabf899bfa7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -462,7 +462,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
     mlir::IntegerAttr align = getAlignmentAttr(addr.getAlignment());
     return cir::LoadOp::create(*this, loc, addr.getPointer(), 
/*isDeref=*/false,
                                isVolatile, /*alignment=*/align,
-                               /*mem_order=*/cir::MemOrderAttr{});
+                               /*mem_order=*/cir::MemOrderAttr{}, 
/*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
@@ -473,7 +473,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
     mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
     return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
                                /*isVolatile=*/false, alignAttr,
-                               /*mem_order=*/cir::MemOrderAttr{});
+                               /*mem_order=*/cir::MemOrderAttr{}, 
/*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::LoadOp
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 70497258eb64a..ef7538f167b90 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -14,6 +14,7 @@
 #include "CIRGenConstantEmitter.h"
 #include "CIRGenFunction.h"
 #include "CIRGenModule.h"
+#include "CIRGenTBAA.h"
 #include "CIRGenValue.h"
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/Value.h"
@@ -426,6 +427,8 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue 
base,
 LValue CIRGenFunction::emitLValueForBitField(LValue base,
                                              const FieldDecl *field) {
   LValueBaseInfo baseInfo = base.getBaseInfo();
+  TBAAAccessInfo tbaaInfo{};
+
   const CIRGenRecordLayout &layout =
       cgm.getTypes().getCIRGenRecordLayout(field->getParent());
   const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
@@ -444,7 +447,7 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
   // TODO(cir): Support TBAA for bit fields.
   assert(!cir::MissingFeatures::opTBAA());
   LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
-  return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
+  return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo, tbaaInfo);
 }
 
 LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) 
{
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp 
b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 33bdfa315a9ea..c38bf6d90c915 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -14,6 +14,7 @@
 
 #include "CIRGenCXXABI.h"
 #include "CIRGenCall.h"
+#include "CIRGenTBAA.h"
 #include "CIRGenValue.h"
 #include "mlir/IR/Location.h"
 #include "clang/AST/ExprCXX.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index a3a7b4a207a81..8d374eb723045 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -16,6 +16,7 @@
 #include "CIRGenBuilder.h"
 #include "CIRGenCall.h"
 #include "CIRGenModule.h"
+#include "CIRGenTBAA.h"
 #include "CIRGenTypeCache.h"
 #include "CIRGenValue.h"
 #include "EHScopeStack.h"
@@ -838,11 +839,13 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   LValue makeAddrLValue(Address addr, QualType ty,
                         AlignmentSource source = AlignmentSource::Type) {
-    return makeAddrLValue(addr, ty, LValueBaseInfo(source));
+    return makeAddrLValue(addr, ty, LValueBaseInfo(source),
+                          cgm.getTBAAAccessInfo(ty));
   }
 
-  LValue makeAddrLValue(Address addr, QualType ty, LValueBaseInfo baseInfo) {
-    return LValue::makeAddr(addr, ty, baseInfo);
+  LValue makeAddrLValue(Address addr, QualType ty, LValueBaseInfo baseInfo,
+                        TBAAAccessInfo tbaaInfo = {}) {
+    return LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
   }
 
   void initializeVTablePointers(mlir::Location loc,
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index e09d3de5aac9a..138ead60d68f0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Interfaces/CIROpInterfaces.h"
 #include "clang/CIR/MissingFeatures.h"
@@ -2492,3 +2493,72 @@ DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
                                          llvm::StringRef feature) {
   return errorNYI(loc.getBegin(), feature) << loc;
 }
+
+cir::TBAAAttr CIRGenModule::getTBAATypeInfo(QualType QTy) {
+  if (!tbaa) {
+    return nullptr;
+  }
+  return tbaa->getTypeInfo(QTy);
+}
+
+TBAAAccessInfo CIRGenModule::getTBAAAccessInfo(QualType accessType) {
+  if (!tbaa) {
+    return TBAAAccessInfo();
+  }
+  if (getLangOpts().CUDAIsDevice) {
+    llvm_unreachable("NYI");
+  }
+  return tbaa->getAccessInfo(accessType);
+}
+
+TBAAAccessInfo
+CIRGenModule::getTBAAVTablePtrAccessInfo(mlir::Type VTablePtrType) {
+  if (!tbaa)
+    return TBAAAccessInfo();
+  llvm_unreachable("NYI");
+  return tbaa->getVTablePtrAccessInfo(VTablePtrType);
+}
+
+mlir::ArrayAttr CIRGenModule::getTBAAStructInfo(QualType QTy) {
+  if (!tbaa)
+    return nullptr;
+  return tbaa->getTBAAStructInfo(QTy);
+}
+
+cir::TBAAAttr CIRGenModule::getTBAABaseTypeInfo(QualType QTy) {
+  if (!tbaa) {
+    return nullptr;
+  }
+  return tbaa->getBaseTypeInfo(QTy);
+}
+
+cir::TBAAAttr CIRGenModule::getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo) {
+  if (!tbaa) {
+    return nullptr;
+  }
+  return tbaa->getAccessTagInfo(tbaaInfo);
+}
+
+TBAAAccessInfo CIRGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
+                                                  TBAAAccessInfo TargetInfo) {
+  if (!tbaa)
+    return TBAAAccessInfo();
+  return tbaa->mergeTBAAInfoForCast(SourceInfo, TargetInfo);
+}
+
+TBAAAccessInfo
+CIRGenModule::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+                                                  TBAAAccessInfo InfoB) {
+  if (!tbaa)
+    return TBAAAccessInfo();
+  return tbaa->mergeTBAAInfoForConditionalOperator(InfoA, InfoB);
+}
+
+TBAAAccessInfo
+CIRGenModule::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
+                                             TBAAAccessInfo SrcInfo) {
+  if (!tbaa)
+    return TBAAAccessInfo();
+  return tbaa->mergeTBAAInfoForConditionalOperator(DestInfo, SrcInfo);
+}
+
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 2c45bb238f95a..9aed53e52eb08 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -15,16 +15,19 @@
 
 #include "CIRGenBuilder.h"
 #include "CIRGenCall.h"
+#include "CIRGenTBAA.h"
 #include "CIRGenTypeCache.h"
 #include "CIRGenTypes.h"
 #include "CIRGenVTables.h"
 #include "CIRGenValue.h"
 
 #include "clang/AST/CharUnits.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDataLayout.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 
 #include "TargetInfo.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/MLIRContext.h"
@@ -85,6 +88,8 @@ class CIRGenModule : public CIRGenTypeCache {
 
   std::unique_ptr<CIRGenCXXABI> abi;
 
+  std::unique_ptr<CIRGenTBAA> tbaa;
+
   CIRGenTypes genTypes;
 
   /// Holds information about C++ vtables.
@@ -324,6 +329,51 @@ class CIRGenModule : public CIRGenTypeCache {
   /// with codegen.
   clang::CharUnits getNaturalTypeAlignment(clang::QualType t,
                                            LValueBaseInfo *baseInfo);
+  /// Get attribute used to describe accesses to objects of
+  /// the given type.
+  cir::TBAAAttr getTBAATypeInfo(QualType QTy);
+
+  /// Get TBAA information that describes an access to an object of the given
+  /// type.
+  TBAAAccessInfo getTBAAAccessInfo(QualType accessType);
+
+  /// Get the TBAA information that describes an access to a virtual table
+  /// pointer.
+  TBAAAccessInfo getTBAAVTablePtrAccessInfo(mlir::Type VTablePtrType);
+
+  mlir::ArrayAttr getTBAAStructInfo(QualType QTy);
+
+  /// Get metadata that describes the given base access type. Return null if 
the
+  /// type is not suitable for use in TBAA access tags.
+  cir::TBAAAttr getTBAABaseTypeInfo(QualType QTy);
+
+  cir::TBAAAttr getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo);
+
+  /// Get merged TBAA information for the purposes of type casts.
+  TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
+                                      TBAAAccessInfo TargetInfo);
+
+  /// Get merged TBAA information for the purposes of conditional operator.
+  TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
+                                                     TBAAAccessInfo InfoB);
+
+  /// Get merged TBAA information for the purposes of memory transfer calls.
+  TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
+                                                TBAAAccessInfo SrcInfo);
+
+  /// Get TBAA information for an access with a given base lvalue.
+  TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) {
+    if (Base.getTBAAInfo().isMayAlias())
+      return TBAAAccessInfo::getMayAliasInfo();
+    return getTBAAAccessInfo(AccessType);
+  }
+
+  template <typename Op>
+  void decorateOperationWithTBAA(Op op, TBAAAccessInfo tbaaInfo) {
+    if (auto tag = getTBAAAccessTagInfo(tbaaInfo)) {
+      op.setTbaaAttr(tag);
+    }
+  }
 
   /// TODO: Add TBAAAccessInfo
   CharUnits getDynamicOffsetAlignment(CharUnits actualBaseAlign,
diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
new file mode 100644
index 0000000000000..9d4e89f6e7a3e
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
@@ -0,0 +1,65 @@
+#include "CIRGenTBAA.h"
+#include "CIRGenTypes.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+
+namespace clang::CIRGen {
+
+static cir::TBAAAttr tbaaNYI(mlir::MLIRContext *ctx) {
+  return cir::TBAAAttr::get(ctx);
+}
+
+CIRGenTBAA::CIRGenTBAA(mlir::MLIRContext *mlirContext,
+                       clang::ASTContext &astContext, CIRGenTypes &types,
+                       mlir::ModuleOp moduleOp,
+                       const clang::CodeGenOptions &codeGenOpts,
+                       const clang::LangOptions &features)
+    : mlirContext(mlirContext), astContext(astContext), types(types),
+      moduleOp(moduleOp), codeGenOpts(codeGenOpts), features(features) {}
+
+cir::TBAAAttr CIRGenTBAA::getTypeInfo(clang::QualType qty) {
+  return tbaaNYI(mlirContext);
+}
+
+TBAAAccessInfo CIRGenTBAA::getAccessInfo(clang::QualType accessType) {
+  return TBAAAccessInfo();
+}
+
+TBAAAccessInfo CIRGenTBAA::getVTablePtrAccessInfo(mlir::Type vtablePtrType) {
+  return TBAAAccessInfo();
+}
+
+mlir::ArrayAttr CIRGenTBAA::getTBAAStructInfo(clang::QualType qty) {
+  return mlir::ArrayAttr::get(mlirContext, {});
+}
+
+cir::TBAAAttr CIRGenTBAA::getBaseTypeInfo(clang::QualType qty) {
+  return tbaaNYI(mlirContext);
+}
+
+cir::TBAAAttr CIRGenTBAA::getAccessTagInfo(TBAAAccessInfo tbaaInfo) {
+  return tbaaNYI(mlirContext);
+}
+
+TBAAAccessInfo CIRGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo sourceInfo,
+                                                TBAAAccessInfo targetInfo) {
+  return TBAAAccessInfo();
+}
+
+TBAAAccessInfo
+CIRGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo infoA,
+                                                TBAAAccessInfo infoB) {
+  return TBAAAccessInfo();
+}
+
+TBAAAccessInfo
+CIRGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo destInfo,
+                                           TBAAAccessInfo srcInfo) {
+  return TBAAAccessInfo();
+}
+
+
+} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.h 
b/clang/lib/CIR/CodeGen/CIRGenTBAA.h
new file mode 100644
index 0000000000000..fc5fbd6c74fcb
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.h
@@ -0,0 +1,188 @@
+//===--- CIRGenTBAA.h - TBAA information for LLVM CIRGen --------*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that manages TBAA information and defines the TBAA policy
+// for the optimizer to use.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENTBAA_H
+#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENTBAA_H
+
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/MLIRContext.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/CodeGenOptions.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+
+namespace clang::CIRGen {
+
+class CIRGenTypes;
+
+enum class TBAAAccessKind : unsigned {
+  Ordinary,
+  MayAlias,
+  Incomplete,
+};
+
+// Describes a memory access in terms of TBAA.
+struct TBAAAccessInfo {
+  TBAAAccessInfo(TBAAAccessKind kind, cir::TBAAAttr baseType,
+                 cir::TBAAAttr accessType, uint64_t offset, uint64_t size)
+      : kind(kind), baseType(baseType), accessType(accessType), offset(offset),
+        size(size) {}
+
+  TBAAAccessInfo(cir::TBAAAttr baseType, cir::TBAAAttr accessType,
+                 uint64_t offset, uint64_t size)
+      : TBAAAccessInfo(TBAAAccessKind::Ordinary, baseType, accessType, offset,
+                       size) {}
+
+  explicit TBAAAccessInfo(cir::TBAAAttr accessType, uint64_t size)
+      : TBAAAccessInfo(TBAAAccessKind::Ordinary, /* baseType= */ {}, 
accessType,
+                       /* offset= */ 0, size) {}
+
+  TBAAAccessInfo()
+      : TBAAAccessInfo(/* accessType= */ nullptr, /* size= */ 0) {};
+
+  static TBAAAccessInfo getMayAliasInfo() {
+    return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* baseType= */ {},
+                          /* accessType= */ nullptr,
+                          /* offset= */ 0, /* size= */ 0);
+  }
+
+  static TBAAAccessInfo getIncompleteInfo() {
+    return TBAAAccessInfo(TBAAAccessKind::Incomplete, /* baseType= */ {},
+                          /* accessType= */ {},
+                          /* offset= */ 0, /* size= */ 0);
+  }
+
+  bool isMayAlias() const { return kind == TBAAAccessKind::MayAlias; }
+
+  bool isIncomplete() const { return kind == TBAAAccessKind::Incomplete; }
+
+  bool operator==(const TBAAAccessInfo &other) const {
+    return kind == other.kind && baseType == other.baseType &&
+           accessType == other.accessType && offset == other.offset &&
+           size == other.size;
+  }
+
+  bool operator!=(const TBAAAccessInfo &other) const {
+    return !(*this == other);
+  }
+
+  explicit operator bool() const { return *this != TBAAAccessInfo(); }
+
+  /// The kind of the access descriptor.
+  TBAAAccessKind kind;
+
+  /// The base/leading access type. May be null if this access
+  /// descriptor represents an access that is not considered to be an access
+  /// to an aggregate or union member.
+  cir::TBAAAttr baseType;
+
+  /// The final access type. May be null if there is no TBAA
+  /// information available about this access.
+  cir::TBAAAttr accessType;
+
+  /// The byte offset of the final access within the base one. Must be
+  /// zero if the base access type is not specified.
+  uint64_t offset;
+
+  /// The size of access, in bytes.
+  uint64_t size;
+};
+
+/// This class organizes the cross-module state that is used while lowering AST
+/// types to LLVM types.
+class CIRGenTBAA {
+  mlir::MLIRContext *mlirContext;
+  [[maybe_unused]] clang::ASTContext &astContext;
+  [[maybe_unused]] CIRGenTypes &types;
+  mlir::ModuleOp moduleOp;
+  [[maybe_unused]] const clang::CodeGenOptions &codeGenOpts;
+  [[maybe_unused]] const clang::LangOptions &features;
+
+public:
+  CIRGenTBAA(mlir::MLIRContext *mlirContext, clang::ASTContext &astContext,
+             CIRGenTypes &types, mlir::ModuleOp moduleOp,
+             const clang::CodeGenOptions &codeGenOpts,
+             const clang::LangOptions &features);
+
+  /// Get attribute used to describe accesses to objects of the given type.
+  cir::TBAAAttr getTypeInfo(clang::QualType qty);
+
+  /// Get TBAA information that describes an access to an object of the given
+  /// type.
+  TBAAAccessInfo getAccessInfo(clang::QualType accessType);
+
+  /// Get the TBAA information that describes an access to a virtual table
+  /// pointer.
+  TBAAAccessInfo getVTablePtrAccessInfo(mlir::Type vtablePtrType);
+
+  /// Get the TBAAStruct attributes to be used for a memcpy of the given type.
+  mlir::ArrayAttr getTBAAStructInfo(clang::QualType qty);
+
+  /// Get attribute that describes the given base access type. Return null if
+  /// the type is not suitable for use in TBAA access tags.
+  cir::TBAAAttr getBaseTypeInfo(clang::QualType qty);
+
+  /// Get TBAA tag for a given memory access.
+  cir::TBAAAttr getAccessTagInfo(TBAAAccessInfo tbaaInfo);
+
+  /// Get merged TBAA information for the purpose of type casts.
+  TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo sourceInfo,
+                                      TBAAAccessInfo targetInfo);
+
+  /// Get merged TBAA information for the purpose of conditional operator.
+  TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo infoA,
+                                                     TBAAAccessInfo infoB);
+
+  /// Get merged TBAA information for the purpose of memory transfer calls.
+  TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo destInfo,
+                                                TBAAAccessInfo srcInfo);
+};
+} // namespace clang::CIRGen
+
+namespace llvm {
+template <> struct DenseMapInfo<clang::CIRGen::TBAAAccessInfo> {
+  static clang::CIRGen::TBAAAccessInfo getEmptyKey() {
+    unsigned unsignedKey = DenseMapInfo<unsigned>::getEmptyKey();
+    return clang::CIRGen::TBAAAccessInfo(
+        static_cast<clang::CIRGen::TBAAAccessKind>(unsignedKey),
+        DenseMapInfo<cir::TBAAAttr>::getEmptyKey(),
+        DenseMapInfo<cir::TBAAAttr>::getEmptyKey(),
+        DenseMapInfo<uint64_t>::getEmptyKey(),
+        DenseMapInfo<uint64_t>::getEmptyKey());
+  }
+  static clang::CIRGen::TBAAAccessInfo getTombstoneKey() {
+    unsigned unsignedKey = DenseMapInfo<unsigned>::getTombstoneKey();
+    return clang::CIRGen::TBAAAccessInfo(
+        static_cast<clang::CIRGen::TBAAAccessKind>(unsignedKey),
+        DenseMapInfo<cir::TBAAAttr>::getTombstoneKey(),
+        DenseMapInfo<cir::TBAAAttr>::getTombstoneKey(),
+        DenseMapInfo<uint64_t>::getTombstoneKey(),
+        DenseMapInfo<uint64_t>::getTombstoneKey());
+  }
+  static unsigned getHashValue(const clang::CIRGen::TBAAAccessInfo &val) {
+    auto kindValue = static_cast<unsigned>(val.kind);
+    return DenseMapInfo<unsigned>::getHashValue(kindValue) ^
+           DenseMapInfo<cir::TBAAAttr>::getHashValue(val.baseType) ^
+           DenseMapInfo<cir::TBAAAttr>::getHashValue(val.accessType) ^
+           DenseMapInfo<uint64_t>::getHashValue(val.offset) ^
+           DenseMapInfo<uint64_t>::getHashValue(val.size);
+  }
+  static bool isEqual(const clang::CIRGen::TBAAAccessInfo &lhs,
+                      const clang::CIRGen::TBAAAccessInfo &rhs) {
+    return lhs == rhs;
+  }
+};
+} // namespace llvm
+
+#endif
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h 
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 2002bd7e7c488..6324292ee4770 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -20,6 +20,7 @@
 #include "clang/AST/Type.h"
 
 #include "CIRGenRecordLayout.h"
+#include "CIRGenTBAA.h"
 #include "mlir/IR/Value.h"
 
 #include "clang/CIR/MissingFeatures.h"
@@ -172,9 +173,11 @@ class LValue {
   mlir::Type elementType;
   LValueBaseInfo baseInfo;
   const CIRGenBitFieldInfo *bitFieldInfo{nullptr};
+  TBAAAccessInfo tbaaInfo;
 
   void initialize(clang::QualType type, clang::Qualifiers quals,
-                  clang::CharUnits alignment, LValueBaseInfo baseInfo) {
+                  clang::CharUnits alignment, LValueBaseInfo baseInfo,
+                  TBAAAccessInfo tbaaInfo) {
     assert((!alignment.isZero() || type->isIncompleteType()) &&
            "initializing l-value with zero alignment!");
     this->type = type;
@@ -223,6 +226,9 @@ class LValue {
     assert(!cir::MissingFeatures::addressIsKnownNonNull());
   }
 
+  TBAAAccessInfo getTBAAInfo() const { return tbaaInfo; }
+  void setTBAAInfo(TBAAAccessInfo info) { tbaaInfo = info; }
+
   const clang::Qualifiers &getQuals() const { return quals; }
   clang::Qualifiers &getQuals() { return quals; }
 
@@ -230,7 +236,8 @@ class LValue {
   void setBaseInfo(LValueBaseInfo info) { baseInfo = info; }
 
   static LValue makeAddr(Address address, clang::QualType t,
-                         LValueBaseInfo baseInfo) {
+                         LValueBaseInfo baseInfo,
+                         TBAAAccessInfo tbaaInfo = {}) {
     // Classic codegen sets the objc gc qualifier here. That requires an
     // ASTContext, which is passed in from CIRGenFunction::makeAddrLValue.
     assert(!cir::MissingFeatures::objCGC());
@@ -239,7 +246,8 @@ class LValue {
     r.lvType = Simple;
     r.v = address.getPointer();
     r.elementType = address.getElementType();
-    r.initialize(t, t.getQualifiers(), address.getAlignment(), baseInfo);
+    r.initialize(t, t.getQualifiers(), address.getAlignment(), baseInfo,
+                 tbaaInfo);
     return r;
   }
 
@@ -274,26 +282,28 @@ class LValue {
   }
 
   static LValue makeVectorElt(Address vecAddress, mlir::Value index,
-                              clang::QualType t, LValueBaseInfo baseInfo) {
+                              clang::QualType t, LValueBaseInfo baseInfo,
+                              TBAAAccessInfo tbaaInfo = {}) {
     LValue r;
     r.lvType = VectorElt;
     r.v = vecAddress.getPointer();
     r.elementType = vecAddress.getElementType();
     r.vectorIdx = index;
-    r.initialize(t, t.getQualifiers(), vecAddress.getAlignment(), baseInfo);
+    r.initialize(t, t.getQualifiers(), vecAddress.getAlignment(), baseInfo,
+                 tbaaInfo);
     return r;
   }
 
   static LValue makeExtVectorElt(Address vecAddress, mlir::ArrayAttr elts,
-                                 clang::QualType type,
-                                 LValueBaseInfo baseInfo) {
+                                 clang::QualType type, LValueBaseInfo baseInfo,
+                                 TBAAAccessInfo tbaaInfo = {}) {
     LValue r;
     r.lvType = ExtVectorElt;
     r.v = vecAddress.getPointer();
     r.elementType = vecAddress.getElementType();
     r.vectorElts = elts;
     r.initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
-                 baseInfo);
+                 baseInfo, tbaaInfo);
     return r;
   }
 
@@ -319,13 +329,15 @@ class LValue {
   /// \param Info - The information describing how to perform the bit-field
   /// access.
   static LValue makeBitfield(Address addr, const CIRGenBitFieldInfo &info,
-                             clang::QualType type, LValueBaseInfo baseInfo) {
+                             clang::QualType type, LValueBaseInfo baseInfo,
+                             TBAAAccessInfo tbaaInfo) {
     LValue r;
     r.lvType = BitField;
     r.v = addr.getPointer();
     r.elementType = addr.getElementType();
     r.bitFieldInfo = &info;
-    r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo);
+    r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo,
+                 tbaaInfo);
     return r;
   }
 };
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt 
b/clang/lib/CIR/CodeGen/CMakeLists.txt
index d3e2290ceea0b..81f844404096f 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -40,6 +40,7 @@ add_clang_library(clangCIR
   CIRGenStmt.cpp
   CIRGenStmtOpenACC.cpp
   CIRGenStmtOpenACCLoop.cpp
+  CIRGenTBAA.cpp
   CIRGenTypes.cpp
   CIRGenVTables.cpp
   TargetInfo.cpp
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 6bf543cf794b7..3568449f873a5 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -78,6 +78,12 @@ struct CIROpAsmDialectInterface : public 
OpAsmDialectInterface {
       os << dynCastInfoAttr.getAlias();
       return AliasResult::FinalAlias;
     }
+
+    if (auto tbaaAttr = mlir::dyn_cast<cir::TBAAAttr>(attr)) {
+      os << tbaaAttr.getMnemonic();
+      return AliasResult::OverridableAlias;
+    }
+
     return AliasResult::NoAlias;
   }
 };
diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp 
b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
index 66469e208d7b0..1e6b88afca233 100644
--- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
@@ -143,7 +143,7 @@ DeletionKind cir::CopyOp::removeBlockingUses(
     cir::StoreOp::create(builder, getLoc(), reachingDefinition, getDst(),
                          /*isVolatile=*/false,
                          /*alignment=*/mlir::IntegerAttr{},
-                         /*mem-order=*/cir::MemOrderAttr());
+                         /*mem-order=*/cir::MemOrderAttr(), 
/*tbaa=*/mlir::ArrayAttr{});
   return DeletionKind::Delete;
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to