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

From cdfac7fffb460c4ddacc19f333ba5bb2ca1c819e Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Fri, 21 Nov 2025 02:39:40 +0100
Subject: [PATCH 1/2] [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/include/clang/CIR/MissingFeatures.h     |   1 +
 clang/lib/CIR/CodeGen/CIRGenAtomic.cpp        |   2 +-
 clang/lib/CIR/CodeGen/CIRGenBuilder.h         |   4 +-
 clang/lib/CIR/CodeGen/CIRGenClass.cpp         |  10 +-
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          |  67 ++++---
 clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp |   8 +-
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp      |   1 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  18 +-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  81 +++++++-
 clang/lib/CIR/CodeGen/CIRGenModule.h          |  52 +++++
 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 +-
 19 files changed, 516 insertions(+), 61 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/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index c99fd6f0bfcc4..defcb5dd600d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -302,6 +302,7 @@ struct MissingFeatures {
   static bool openCL() { return false; }
   static bool openMP() { return false; }
   static bool opTBAA() { return false; }
+  static bool opTBAAStruct() { return false; }
   static bool peepholeProtection() { return false; }
   static bool pgoUse() { return false; }
   static bool pointerAuthentication() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 48c082d89de18..aea832051b355 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -1011,7 +1011,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, 
LValue dest,
     if (isVolatile)
       store.setIsVolatile(true);
 
-    assert(!cir::MissingFeatures::opLoadStoreTbaa());
+    cgm.decorateOperationWithTBAA(store, dest.getTBAAInfo());
     return;
   }
 
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/CIRGenClass.cpp 
b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 0f10347944fae..b775317a6a0c0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -429,7 +429,15 @@ void 
CIRGenFunction::initializeVTablePointer(mlir::Location loc,
       builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
   Address vtableField = Address(vtablePtr, classAddr.getAlignment());
   builder.createStore(loc, vtableAddressPoint, vtableField);
-  assert(!cir::MissingFeatures::opTBAA());
+
+  cir::StoreOp storeOp = builder.createStore(loc, vtableAddressPoint, 
vtableField);
+  TBAAAccessInfo tbaaInfo =
+      cgm.getTBAAVTablePtrAccessInfo(vtableAddressPoint.getType());
+  cgm.decorateOperationWithTBAA(storeOp, tbaaInfo);
+  if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
+      cgm.getCodeGenOpts().StrictVTablePointers) {
+  }
+
   assert(!cir::MissingFeatures::createInvariantGroup());
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 70497258eb64a..dd1143c9301b1 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"
@@ -69,7 +70,8 @@ Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
 /// Given an expression of pointer type, try to
 /// derive a more accurate bound on the alignment of the pointer.
 Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
-                                                 LValueBaseInfo *baseInfo) {
+                                                 LValueBaseInfo *baseInfo,
+                                                TBAAAccessInfo *tbaaInfo) {
   // We allow this with ObjC object pointers because of fragile ABIs.
   assert(expr->getType()->isPointerType() ||
          expr->getType()->isObjCObjectPointerType());
@@ -98,12 +100,18 @@ Address CIRGenFunction::emitPointerWithAlignment(const 
Expr *expr,
           *baseInfo = innerBaseInfo;
 
         if (isa<ExplicitCastExpr>(ce)) {
-          LValueBaseInfo targetTypeBaseInfo;
-
           const QualType pointeeType = expr->getType()->getPointeeType();
+
+          LValueBaseInfo targetTypeBaseInfo;
           const CharUnits align =
               cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
 
+          if (tbaaInfo) {
+            TBAAAccessInfo targetTypeTbaaInfo = 
cgm.getTBAAAccessInfo(pointeeType);
+            *tbaaInfo =
+                cgm.mergeTBAAInfoForCast(*tbaaInfo, targetTypeTbaaInfo);
+          }
+
           // If the source l-value is opaque, honor the alignment of the
           // casted-to type.
           if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
@@ -315,7 +323,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, 
const Expr *e,
 
 void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
                                        bool isVolatile, QualType ty,
-                                       LValueBaseInfo baseInfo, bool isInit,
+                                       LValueBaseInfo baseInfo, TBAAAccessInfo 
tbaaInfo,
+                                       bool isInit,
                                        bool isNontemporal) {
   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
 
@@ -338,8 +347,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, 
Address addr,
 
   value = emitToMemory(value, ty);
 
-  assert(!cir::MissingFeatures::opLoadStoreTbaa());
-  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
   if (ty->isAtomicType() ||
       (!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {
     emitAtomicStore(RValue::get(value), atomicLValue, isInit);
@@ -357,14 +365,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, 
Address addr,
   }
 
   assert(currSrcLoc && "must pass in source location");
-  builder.createStore(*currSrcLoc, value, addr, isVolatile);
+  cir::StoreOp store = builder.createStore(*currSrcLoc, value, addr, 
isVolatile);
+  cgm.decorateOperationWithTBAA(store, tbaaInfo);
 
   if (isNontemporal) {
     cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
     return;
   }
-
-  assert(!cir::MissingFeatures::opTBAA());
 }
 
 // TODO: Replace this with a proper TargetInfo function call.
@@ -426,6 +433,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 +453,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) 
{
@@ -457,7 +466,10 @@ LValue CIRGenFunction::emitLValueForField(LValue base, 
const FieldDecl *field) {
   const RecordDecl *rec = field->getParent();
   AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
   LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
-  assert(!cir::MissingFeatures::opTBAA());
+  TBAAAccessInfo fieldTbaaInfo{};
+
+  // TODO(cir): Initialize tbaa info
+  assert(!MissingFeatures::opTBAA());
 
   Address addr = base.getAddress();
   if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
@@ -489,11 +501,11 @@ LValue CIRGenFunction::emitLValueForField(LValue base, 
const FieldDecl *field) {
   // If this is a reference field, load the reference right now.
   if (fieldType->isReferenceType()) {
     assert(!cir::MissingFeatures::opTBAA());
-    LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo);
+    LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo, 
fieldTbaaInfo);
     if (recordCVR & Qualifiers::Volatile)
       refLVal.getQuals().addVolatile();
     addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),
-                               &fieldBaseInfo);
+                               &fieldBaseInfo, &fieldTbaaInfo);
 
     // Qualifiers on the struct don't apply to the referencee.
     recordCVR = 0;
@@ -561,13 +573,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, 
LValue lvalue,
   }
 
   emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
-                    lvalue.getType(), lvalue.getBaseInfo(), isInit,
+                    lvalue.getType(), lvalue.getBaseInfo(), 
lvalue.getTBAAInfo(), isInit,
                     /*isNontemporal=*/false);
 }
 
 mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
                                              QualType ty, SourceLocation loc,
-                                             LValueBaseInfo baseInfo) {
+                                             LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo) {
   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
   mlir::Type eltTy = addr.getElementType();
 
@@ -586,8 +598,7 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, 
bool isVolatile,
                    "emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
   }
 
-  assert(!cir::MissingFeatures::opLoadStoreTbaa());
-  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+  LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
   if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))
     cgm.errorNYI("emitLoadOfScalar: load atomic");
 
@@ -596,19 +607,21 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address 
addr, bool isVolatile,
 
   assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());
 
-  mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+  cir::LoadOp loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+  cgm.decorateOperationWithTBAA(loadOp, tbaaInfo);
+
   if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
     cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
 
+
   return loadOp;
 }
 
 mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
                                              SourceLocation loc) {
   assert(!cir::MissingFeatures::opLoadStoreNontemporal());
-  assert(!cir::MissingFeatures::opLoadStoreTbaa());
   return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
-                          lvalue.getType(), loc, lvalue.getBaseInfo());
+                          lvalue.getType(), loc, lvalue.getBaseInfo(), 
lvalue.getTBAAInfo());
 }
 
 /// Given an expression that represents a value lvalue, this
@@ -2285,17 +2298,19 @@ RValue CIRGenFunction::emitReferenceBindingToExpr(const 
Expr *e) {
 }
 
 Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
-                                            LValueBaseInfo *pointeeBaseInfo) {
+                                            LValueBaseInfo *pointeeBaseInfo, 
TBAAAccessInfo *pointeeTbaaInfo) {
   if (refLVal.isVolatile())
     cgm.errorNYI(loc, "load of volatile reference");
 
+  QualType pointeeType = refLVal.getType()->getPointeeType();
   cir::LoadOp load =
       cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),
                           refLVal.getAddress().getPointer());
 
-  assert(!cir::MissingFeatures::opTBAA());
+  cgm.decorateOperationWithTBAA(load, refLVal.getTBAAInfo());
+  if (pointeeTbaaInfo)
+    *pointeeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
 
-  QualType pointeeType = refLVal.getType()->getPointeeType();
   CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
   return Address(load, convertTypeForMem(pointeeType), align);
 }
@@ -2306,10 +2321,10 @@ LValue 
CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
                                                  AlignmentSource source) {
   LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
   LValueBaseInfo pointeeBaseInfo;
-  assert(!cir::MissingFeatures::opTBAA());
-  Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
+  TBAAAccessInfo tbaaAccessInfo;
+  Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, 
&tbaaAccessInfo);
   return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
-                        pointeeBaseInfo);
+                        pointeeBaseInfo, tbaaAccessInfo);
 }
 
 void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 872fc8d14ad95..b466b68b8f0ae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -983,7 +983,13 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue 
src, QualType ty,
   [[maybe_unused]] cir::CopyOp copyOp =
       builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), 
isVolatile);
 
-  assert(!cir::MissingFeatures::opTBAA());
+  assert(!cir::MissingFeatures::opTBAAStruct());
+
+  if (cgm.getCodeGenOpts().NewStructPathTBAA) {
+    TBAAAccessInfo tbaaInfo = cgm.mergeTBAAInfoForMemoryTransfer(
+        dest.getTBAAInfo(), src.getTBAAInfo());
+    cgm.decorateOperationWithTBAA(copyOp, tbaaInfo);
+  }
 }
 
 // TODO(cir): This could be shared with classic codegen.
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..53512163596cd 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,
@@ -1670,7 +1673,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   RValue emitLoadOfLValue(LValue lv, SourceLocation loc);
 
   Address emitLoadOfReference(LValue refLVal, mlir::Location loc,
-                              LValueBaseInfo *pointeeBaseInfo);
+                              LValueBaseInfo *pointeeBaseInfo, TBAAAccessInfo 
*pointeeTbaaInfo);
   LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc,
                                    QualType refTy, AlignmentSource source);
 
@@ -1680,7 +1683,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// l-value.
   mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc);
   mlir::Value emitLoadOfScalar(Address addr, bool isVolatile, QualType ty,
-                               SourceLocation loc, LValueBaseInfo baseInfo);
+                               SourceLocation loc, LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo);
 
   /// Emit code to compute a designator that specifies the location
   /// of the expression.
@@ -1719,7 +1722,8 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// reasonable to just ignore the returned alignment when it isn't from an
   /// explicit source.
   Address emitPointerWithAlignment(const clang::Expr *expr,
-                                   LValueBaseInfo *baseInfo = nullptr);
+                                   LValueBaseInfo *baseInfo = nullptr,
+                                  TBAAAccessInfo *tbaaInfo = nullptr);
 
   /// Emits a reference binding to the passed in expression.
   RValue emitReferenceBindingToExpr(const Expr *e);
@@ -1748,7 +1752,7 @@ class CIRGenFunction : public CIRGenTypeCache {
                           bool isInit);
 
   void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
-                         clang::QualType ty, LValueBaseInfo baseInfo,
+                         clang::QualType ty, LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo,
                          bool isInit = false, bool isNontemporal = false);
   void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index e09d3de5aac9a..d36973f2a1e3c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -20,12 +20,15 @@
 #include "clang/AST/DeclOpenACC.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/RecordLayout.h"
+#include "clang/AST/TypeBase.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"
 
 #include "CIRGenFunctionInfo.h"
+#include "CIRGenTBAA.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/Location.h"
 #include "mlir/IR/MLIRContext.h"
@@ -96,6 +99,13 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
               astContext.getTargetInfo().getPointerAlign(LangAS::Default))
           .getQuantity();
 
+
+  // Enable TBAA unless it's suppressed. TSan and TySan need TBAA even at O0.
+  if (langOpts.Sanitize.hasOneOf(SanitizerKind::Thread | SanitizerKind::Type) 
||
+      (!codeGenOpts.RelaxedAliasing && codeGenOpts.OptimizationLevel > 0))
+    tbaa = std::make_unique<CIRGenTBAA>(&mlirContext, astContext, getTypes(), 
theModule, codeGenOpts,
+                               getLangOpts());
+
   const unsigned charSize = astContext.getTargetInfo().getCharWidth();
   uCharTy = cir::IntType::get(&getMLIRContext(), charSize, /*isSigned=*/false);
 
@@ -160,7 +170,6 @@ CharUnits CIRGenModule::getClassPointerAlignment(const 
CXXRecordDecl *rd) {
 
 CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
                                                 LValueBaseInfo *baseInfo) {
-  assert(!cir::MissingFeatures::opTBAA());
 
   // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown, but
   // that doesn't return the information we need to compute baseInfo.
@@ -2492,3 +2501,73 @@ DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
                                          llvm::StringRef feature) {
   return errorNYI(loc.getBegin(), feature) << loc;
 }
+
+cir::TBAAAttr CIRGenModule::getTBAATypeInfo(QualType type) {
+  if (!tbaa) {
+    return nullptr;
+  }
+  return tbaa->getTypeInfo(type);
+}
+
+TBAAAccessInfo CIRGenModule::getTBAAAccessInfo(QualType accessType) {
+  if (!tbaa) {
+    return TBAAAccessInfo{};
+  }
+  if (getLangOpts().CUDAIsDevice) {
+    llvm_unreachable("TBAA access NYI");
+  }
+  return tbaa->getAccessInfo(accessType);
+}
+
+TBAAAccessInfo
+CIRGenModule::getTBAAVTablePtrAccessInfo(mlir::Type vTablePtrType) {
+  if (!tbaa)
+    return TBAAAccessInfo{};
+
+  llvm_unreachable("TBAA vtable pointer access NYI");
+  return tbaa->getVTablePtrAccessInfo(vTablePtrType);
+}
+
+mlir::ArrayAttr CIRGenModule::getTBAAStructInfo(QualType type) {
+  if (!tbaa)
+    return nullptr;
+  return tbaa->getTBAAStructInfo(type);
+}
+
+cir::TBAAAttr CIRGenModule::getTBAABaseTypeInfo(QualType type) {
+  if (!tbaa) {
+    return nullptr;
+  }
+  return tbaa->getBaseTypeInfo(type);
+}
+
+mlir::ArrayAttr 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..d83575226231e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -15,17 +15,21 @@
 
 #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/BuiltinAttributes.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/MLIRContext.h"
 #include "clang/AST/Decl.h"
@@ -85,6 +89,8 @@ class CIRGenModule : public CIRGenTypeCache {
 
   std::unique_ptr<CIRGenCXXABI> abi;
 
+  std::unique_ptr<CIRGenTBAA> tbaa;
+
   CIRGenTypes genTypes;
 
   /// Holds information about C++ vtables.
@@ -325,6 +331,52 @@ class CIRGenModule : public CIRGenTypeCache {
   clang::CharUnits getNaturalTypeAlignment(clang::QualType t,
                                            LValueBaseInfo *baseInfo);
 
+  /// Get attribute used to describe accesses to objects of
+  /// the given type.
+  cir::TBAAAttr getTBAATypeInfo(QualType type);
+
+  /// 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 type);
+
+  /// 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 type);
+
+  mlir::ArrayAttr 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 (mlir::ArrayAttr tag = getTBAAAccessTagInfo(tbaaInfo)) {
+      op.setTbaaAttr(tag);
+    }
+  }
+
   /// TODO: Add TBAAAccessInfo
   CharUnits getDynamicOffsetAlignment(CharUnits actualBaseAlign,
                                       const CXXRecordDecl *baseDecl,
diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
new file mode 100644
index 0000000000000..a6e1667875695
--- /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);
+}
+
+mlir::ArrayAttr CIRGenTBAA::getAccessTagInfo(TBAAAccessInfo tbaaInfo) {
+  return mlir::ArrayAttr::get(mlirContext, {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..c05e8f4e6f964
--- /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.
+  mlir::ArrayAttr 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..daa8b6cf4b7ea 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -61,7 +61,6 @@ struct CIROpAsmDialectInterface : public 
OpAsmDialectInterface {
       os << voidType.getAlias();
       return AliasResult::OverridableAlias;
     }
-
     return AliasResult::NoAlias;
   }
 
@@ -78,6 +77,11 @@ 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;
 }
 

From 4f31e5226aaa2643793b995a1befe40f9ff7a7bb Mon Sep 17 00:00:00 2001
From: hhuebner <[email protected]>
Date: Mon, 24 Nov 2025 18:16:31 +0100
Subject: [PATCH 2/2] fmt

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |  9 +++--
 clang/lib/CIR/CodeGen/CIRGenBuilder.h         |  6 ++--
 clang/lib/CIR/CodeGen/CIRGenClass.cpp         |  3 +-
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          | 34 +++++++++++--------
 clang/lib/CIR/CodeGen/CIRGenFunction.h        | 13 ++++---
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  6 ++--
 clang/lib/CIR/CodeGen/CIRGenTBAA.cpp          |  1 -
 clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp    |  3 +-
 8 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 371f046c25ba0..19521ea4d2ebf 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,8 @@ 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{}, 
/*tbaa=*/mlir::ArrayAttr{});
+                               alignmentAttr, cir::MemOrderAttr{},
+                               /*tbaa=*/mlir::ArrayAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -321,14 +322,16 @@ 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, 
/*tbaa=*/mlir::ArrayAttr{});
+    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, /*tbaa=*/mlir::ArrayAttr{});
+    return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order,
+                                /*tbaa=*/mlir::ArrayAttr{});
   }
 
   [[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 98cabf899bfa7..99803dc8aaac3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -462,7 +462,8 @@ 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{}, 
/*tbaa=*/mlir::ArrayAttr{});
+                               /*mem_order=*/cir::MemOrderAttr{},
+                               /*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
@@ -473,7 +474,8 @@ 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{}, 
/*tbaa=*/mlir::ArrayAttr{});
+                               /*mem_order=*/cir::MemOrderAttr{},
+                               /*tbaa=*/mlir::ArrayAttr{});
   }
 
   cir::LoadOp
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp 
b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index b775317a6a0c0..a619b1b1009cd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -430,7 +430,8 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location 
loc,
   Address vtableField = Address(vtablePtr, classAddr.getAlignment());
   builder.createStore(loc, vtableAddressPoint, vtableField);
 
-  cir::StoreOp storeOp = builder.createStore(loc, vtableAddressPoint, 
vtableField);
+  cir::StoreOp storeOp =
+      builder.createStore(loc, vtableAddressPoint, vtableField);
   TBAAAccessInfo tbaaInfo =
       cgm.getTBAAVTablePtrAccessInfo(vtableAddressPoint.getType());
   cgm.decorateOperationWithTBAA(storeOp, tbaaInfo);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index dd1143c9301b1..5981218758dc4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -71,7 +71,7 @@ Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
 /// derive a more accurate bound on the alignment of the pointer.
 Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
                                                  LValueBaseInfo *baseInfo,
-                                                TBAAAccessInfo *tbaaInfo) {
+                                                 TBAAAccessInfo *tbaaInfo) {
   // We allow this with ObjC object pointers because of fragile ABIs.
   assert(expr->getType()->isPointerType() ||
          expr->getType()->isObjCObjectPointerType());
@@ -107,9 +107,9 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr 
*expr,
               cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
 
           if (tbaaInfo) {
-            TBAAAccessInfo targetTypeTbaaInfo = 
cgm.getTBAAAccessInfo(pointeeType);
-            *tbaaInfo =
-                cgm.mergeTBAAInfoForCast(*tbaaInfo, targetTypeTbaaInfo);
+            TBAAAccessInfo targetTypeTbaaInfo =
+                cgm.getTBAAAccessInfo(pointeeType);
+            *tbaaInfo = cgm.mergeTBAAInfoForCast(*tbaaInfo, 
targetTypeTbaaInfo);
           }
 
           // If the source l-value is opaque, honor the alignment of the
@@ -323,8 +323,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, 
const Expr *e,
 
 void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
                                        bool isVolatile, QualType ty,
-                                       LValueBaseInfo baseInfo, TBAAAccessInfo 
tbaaInfo,
-                                       bool isInit,
+                                       LValueBaseInfo baseInfo,
+                                       TBAAAccessInfo tbaaInfo, bool isInit,
                                        bool isNontemporal) {
   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
 
@@ -365,7 +365,8 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, 
Address addr,
   }
 
   assert(currSrcLoc && "must pass in source location");
-  cir::StoreOp store = builder.createStore(*currSrcLoc, value, addr, 
isVolatile);
+  cir::StoreOp store =
+      builder.createStore(*currSrcLoc, value, addr, isVolatile);
   cgm.decorateOperationWithTBAA(store, tbaaInfo);
 
   if (isNontemporal) {
@@ -501,7 +502,8 @@ LValue CIRGenFunction::emitLValueForField(LValue base, 
const FieldDecl *field) {
   // If this is a reference field, load the reference right now.
   if (fieldType->isReferenceType()) {
     assert(!cir::MissingFeatures::opTBAA());
-    LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo, 
fieldTbaaInfo);
+    LValue refLVal =
+        makeAddrLValue(addr, fieldType, fieldBaseInfo, fieldTbaaInfo);
     if (recordCVR & Qualifiers::Volatile)
       refLVal.getQuals().addVolatile();
     addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),
@@ -573,13 +575,15 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, 
LValue lvalue,
   }
 
   emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
-                    lvalue.getType(), lvalue.getBaseInfo(), 
lvalue.getTBAAInfo(), isInit,
+                    lvalue.getType(), lvalue.getBaseInfo(),
+                    lvalue.getTBAAInfo(), isInit,
                     /*isNontemporal=*/false);
 }
 
 mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
                                              QualType ty, SourceLocation loc,
-                                             LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo) {
+                                             LValueBaseInfo baseInfo,
+                                             TBAAAccessInfo tbaaInfo) {
   assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
   mlir::Type eltTy = addr.getElementType();
 
@@ -613,7 +617,6 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, 
bool isVolatile,
   if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
     cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
 
-
   return loadOp;
 }
 
@@ -621,7 +624,8 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
                                              SourceLocation loc) {
   assert(!cir::MissingFeatures::opLoadStoreNontemporal());
   return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
-                          lvalue.getType(), loc, lvalue.getBaseInfo(), 
lvalue.getTBAAInfo());
+                          lvalue.getType(), loc, lvalue.getBaseInfo(),
+                          lvalue.getTBAAInfo());
 }
 
 /// Given an expression that represents a value lvalue, this
@@ -2298,7 +2302,8 @@ RValue CIRGenFunction::emitReferenceBindingToExpr(const 
Expr *e) {
 }
 
 Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
-                                            LValueBaseInfo *pointeeBaseInfo, 
TBAAAccessInfo *pointeeTbaaInfo) {
+                                            LValueBaseInfo *pointeeBaseInfo,
+                                            TBAAAccessInfo *pointeeTbaaInfo) {
   if (refLVal.isVolatile())
     cgm.errorNYI(loc, "load of volatile reference");
 
@@ -2322,7 +2327,8 @@ LValue CIRGenFunction::emitLoadOfReferenceLValue(Address 
refAddr,
   LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
   LValueBaseInfo pointeeBaseInfo;
   TBAAAccessInfo tbaaAccessInfo;
-  Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, 
&tbaaAccessInfo);
+  Address pointeeAddr =
+      emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, &tbaaAccessInfo);
   return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
                         pointeeBaseInfo, tbaaAccessInfo);
 }
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 53512163596cd..e0a57c358c06b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1673,7 +1673,8 @@ class CIRGenFunction : public CIRGenTypeCache {
   RValue emitLoadOfLValue(LValue lv, SourceLocation loc);
 
   Address emitLoadOfReference(LValue refLVal, mlir::Location loc,
-                              LValueBaseInfo *pointeeBaseInfo, TBAAAccessInfo 
*pointeeTbaaInfo);
+                              LValueBaseInfo *pointeeBaseInfo,
+                              TBAAAccessInfo *pointeeTbaaInfo);
   LValue emitLoadOfReferenceLValue(Address refAddr, mlir::Location loc,
                                    QualType refTy, AlignmentSource source);
 
@@ -1683,7 +1684,8 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// l-value.
   mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc);
   mlir::Value emitLoadOfScalar(Address addr, bool isVolatile, QualType ty,
-                               SourceLocation loc, LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo);
+                               SourceLocation loc, LValueBaseInfo baseInfo,
+                               TBAAAccessInfo tbaaInfo);
 
   /// Emit code to compute a designator that specifies the location
   /// of the expression.
@@ -1723,7 +1725,7 @@ class CIRGenFunction : public CIRGenTypeCache {
   /// explicit source.
   Address emitPointerWithAlignment(const clang::Expr *expr,
                                    LValueBaseInfo *baseInfo = nullptr,
-                                  TBAAAccessInfo *tbaaInfo = nullptr);
+                                   TBAAAccessInfo *tbaaInfo = nullptr);
 
   /// Emits a reference binding to the passed in expression.
   RValue emitReferenceBindingToExpr(const Expr *e);
@@ -1752,8 +1754,9 @@ class CIRGenFunction : public CIRGenTypeCache {
                           bool isInit);
 
   void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
-                         clang::QualType ty, LValueBaseInfo baseInfo, 
TBAAAccessInfo tbaaInfo,
-                         bool isInit = false, bool isNontemporal = false);
+                         clang::QualType ty, LValueBaseInfo baseInfo,
+                         TBAAAccessInfo tbaaInfo, bool isInit = false,
+                         bool isNontemporal = false);
   void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
 
   /// Store the specified rvalue into the specified
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index d36973f2a1e3c..0b9834c6bffbc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -99,12 +99,11 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
               astContext.getTargetInfo().getPointerAlign(LangAS::Default))
           .getQuantity();
 
-
   // Enable TBAA unless it's suppressed. TSan and TySan need TBAA even at O0.
   if (langOpts.Sanitize.hasOneOf(SanitizerKind::Thread | SanitizerKind::Type) 
||
       (!codeGenOpts.RelaxedAliasing && codeGenOpts.OptimizationLevel > 0))
-    tbaa = std::make_unique<CIRGenTBAA>(&mlirContext, astContext, getTypes(), 
theModule, codeGenOpts,
-                               getLangOpts());
+    tbaa = std::make_unique<CIRGenTBAA>(&mlirContext, astContext, getTypes(),
+                                        theModule, codeGenOpts, getLangOpts());
 
   const unsigned charSize = astContext.getTargetInfo().getCharWidth();
   uCharTy = cir::IntType::get(&getMLIRContext(), charSize, /*isSigned=*/false);
@@ -2570,4 +2569,3 @@ 
CIRGenModule::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo destInfo,
     return TBAAAccessInfo();
   return tbaa->mergeTBAAInfoForConditionalOperator(destInfo, srcInfo);
 }
-
diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
index a6e1667875695..9db01e85c5e44 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp
@@ -61,5 +61,4 @@ CIRGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo 
destInfo,
   return TBAAAccessInfo();
 }
 
-
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp 
b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
index 1e6b88afca233..39c67e3f13163 100644
--- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp
@@ -143,7 +143,8 @@ DeletionKind cir::CopyOp::removeBlockingUses(
     cir::StoreOp::create(builder, getLoc(), reachingDefinition, getDst(),
                          /*isVolatile=*/false,
                          /*alignment=*/mlir::IntegerAttr{},
-                         /*mem-order=*/cir::MemOrderAttr(), 
/*tbaa=*/mlir::ArrayAttr{});
+                         /*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