diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 48d1f1faf53f..771b7dd33cd4 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -170,7 +170,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { /*alignment=*/intAttr, /*mem_order=*/ cir::MemOrderAttr{}, - /*tbaa=*/cir::TBAAAttr{}); + /*tbaa=*/mlir::ArrayAttr{}); } mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr, @@ -357,7 +357,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { val.getType()) dst = createPtrBitcast(dst, val.getType()); return create(loc, val, dst, _volatile, align, order, - /*tbaa=*/cir::TBAAAttr{}); + /*tbaa=*/mlir::ArrayAttr{}); } mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType, @@ -405,7 +405,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::CopyOp createCopy(mlir::Value dst, mlir::Value src, bool isVolatile = false) { return create(dst.getLoc(), dst, src, isVolatile, - /*tbaa=*/cir::TBAAAttr{}); + /*tbaa=*/mlir::ArrayAttr{}); } cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst, diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index e968d4c27fd5..e54b52b96c91 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -24,9 +24,8 @@ include "clang/CIR/Interfaces/ASTAttrInterfaces.td" // CIR Attrs //===----------------------------------------------------------------------===// -class CIR_Attr traits = [], - string baseCppClass = "::mlir::Attribute"> - : AttrDef { +class CIR_Attr traits = []> + : AttrDef { let mnemonic = attrMnemonic; } @@ -1295,7 +1294,8 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues", let genVerifyDecl = 1; } -include "clang/CIR/Dialect/IR/CIRTBAAAttrs.td" +def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> { +} include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td" diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 36793ba97d52..e02194ad15e0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -588,7 +588,7 @@ def LoadOp : CIR_Op<"load", [ UnitAttr:$is_volatile, OptionalAttr:$alignment, OptionalAttr:$mem_order, - OptionalAttr:$tbaa + OptionalAttr:$tbaa ); let results = (outs CIR_AnyType:$result); @@ -657,7 +657,7 @@ def StoreOp : CIR_Op<"store", [ UnitAttr:$is_volatile, OptionalAttr:$alignment, OptionalAttr:$mem_order, - OptionalAttr:$tbaa); + OptionalAttr:$tbaa); let assemblyFormat = [{ (`volatile` $is_volatile^)? @@ -4068,7 +4068,7 @@ def CopyOp : CIR_Op<"copy", let arguments = (ins Arg:$dst, Arg:$src, UnitAttr:$is_volatile, - OptionalAttr:$tbaa); + OptionalAttr:$tbaa); let summary = "Copies contents from a CIR pointer to another"; let description = [{ Given two CIR pointers, `src` and `dst`, `cir.copy` will copy the memory diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTBAAAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRTBAAAttrs.td deleted file mode 100644 index d46880e8541e..000000000000 --- a/clang/include/clang/CIR/Dialect/IR/CIRTBAAAttrs.td +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// TBAAAttr -//===----------------------------------------------------------------------===// - -def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> { - let summary = "CIR dialect TBAA base attribute"; -} - -//===----------------------------------------------------------------------===// -// TBAAScalarAttr -//===----------------------------------------------------------------------===// - -def CIR_TBAAScalarAttr : CIR_Attr<"TBAAScalar", "tbaa_scalar", [], "TBAAAttr"> { - let summary = "Describes a scalar type in TBAA with an identifier."; - - let parameters = (ins CIR_AnyScalarType : $type); - - let description = [{ - Define a TBAA attribute. - - Example: - ```mlir - // CIR_TBAAScalarAttr - #tbaa_scalar = #cir.tbaa_scalar - #tbaa_scalar1 = #cir.tbaa_scalar - ``` - - See the following link for more details: - https://llvm.org/docs/LangRef.html#tbaa-metadata - }]; - - let assemblyFormat = "`<` struct(params) `>`"; -} - -def CIR_AnyTBAAAttr : AnyAttrOf<[ - CIR_TBAAAttr, - CIR_TBAAScalarAttr -]>; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 68b27a053176..d3f49716301d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -74,28 +74,6 @@ def CIR_IntType : CIR_Type<"Int", "int", static bool isValidPrimitiveIntBitwidth(unsigned width) { return width == 8 || width == 16 || width == 32 || width == 64; } - - llvm::StringRef getTBAATypeName() const { - switch (getWidth()) { - case 1: - case 8: { - return "omnipotent char"; - } - case 16: { - return "short"; - } - case 32: { - return "int"; - } - case 64: { - return "long"; - } - default: { - llvm::errs() << "unknown type: " << *this << "\n"; - return "unknown"; - } - } - } }]; let genVerifyDecl = 1; } @@ -631,11 +609,4 @@ def CIR_AnyType : AnyTypeOf<[ CIR_ComplexType ]>; -def CIR_AnyScalarType : AnyTypeOf<[ - CIR_IntType, CIR_PointerType, CIR_DataMemberType, CIR_MethodType, - CIR_BoolType, CIR_ArrayType, CIR_VectorType, CIR_FuncType, CIR_VoidType, - CIR_ExceptionType, CIR_AnyFloat, CIR_FP16, CIR_BFloat16, - CIR_ComplexType -]>; - #endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 346719691a5d..c0707d687fca 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -58,12 +58,7 @@ struct MissingFeatures { // sanitizer related type check features static bool emitTypeCheck() { return false; } static bool tbaa() { return false; } - static bool tbaaStruct() { return false; } - static bool tbaaTagForStruct() { return false; } - static bool tbaaVTablePtr() { return false; } - static bool tbaaIncompleteType() { return false; } - static bool tbaaMergeTBAAInfo() { return false; } - static bool tbaaMayAlias() { return false; } + static bool tbaa_struct() { return false; } static bool cleanups() { return false; } static bool emitNullabilityCheck() { return false; } static bool ptrAuth() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 3019ca8ef62b..28be733f62d7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -839,7 +839,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { return create( loc, addr.getElementType(), addr.getPointer(), /*isDeref=*/false, /*is_volatile=*/isVolatile, /*alignment=*/mlir::IntegerAttr{}, - /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/cir::TBAAAttr{}); + /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{}); } mlir::Value createAlignedLoad(mlir::Location loc, mlir::Type ty, diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp index 831e2e8c3ae6..44e214fb1f55 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp @@ -1722,7 +1722,7 @@ void CIRGenFunction::emitAggregateCopy(LValue Dest, LValue Src, QualType Ty, // Determine the metadata to describe the position of any padding in this // memcpy, as well as the TBAA tags for the members of the struct, in case // the optimizer wishes to expand it in to scalar memory operations. - assert(!cir::MissingFeatures::tbaaStruct() && "tbaa.struct NYI"); + assert(!cir::MissingFeatures::tbaa_struct() && "tbaa.struct NYI"); if (CGM.getCodeGenOpts().NewStructPathTBAA) { TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForMemoryTransfer( Dest.getTBAAInfo(), Src.getTBAAInfo()); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 2a2557f1fdda..b35ef11c7782 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -3995,7 +3995,7 @@ cir::TBAAAttr CIRGenModule::getTBAABaseTypeInfo(QualType QTy) { return tbaa->getBaseTypeInfo(QTy); } -cir::TBAAAttr CIRGenModule::getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo) { +mlir::ArrayAttr CIRGenModule::getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo) { if (!tbaa) { return nullptr; } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index dd8a0c98b081..905754a4ad3a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -525,7 +525,7 @@ class CIRGenModule : public CIRGenTypeCache { /// type is not suitable for use in TBAA access tags. cir::TBAAAttr getTBAABaseTypeInfo(QualType QTy); - cir::TBAAAttr getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo); + mlir::ArrayAttr getTBAAAccessTagInfo(TBAAAccessInfo tbaaInfo); /// Get merged TBAA information for the purposes of type casts. TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp index ce2969d130ff..a6efc05e4110 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.cpp @@ -1,12 +1,11 @@ #include "CIRGenTBAA.h" +#include "CIRGenCXXABI.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" -#include "clang/CIR/Dialect/IR/CIRTypes.h" -#include "clang/CIR/MissingFeatures.h" #include "llvm/Support/ErrorHandling.h" namespace clang::CIRGen { @@ -22,159 +21,44 @@ CIRGenTBAA::CIRGenTBAA(mlir::MLIRContext *mlirContext, : mlirContext(mlirContext), astContext(astContext), types(types), moduleOp(moduleOp), codeGenOpts(codeGenOpts), features(features) {} -cir::TBAAAttr CIRGenTBAA::getChar() { - return cir::TBAAScalarAttr::get(mlirContext, - cir::IntType::get(mlirContext, 1, true)); -} - -static bool typeHasMayAlias(clang::QualType qty) { - // Tagged types have declarations, and therefore may have attributes. - if (auto *td = qty->getAsTagDecl()) - if (td->hasAttr()) - return true; - - // Also look for may_alias as a declaration attribute on a typedef. - // FIXME: We should follow GCC and model may_alias as a type attribute - // rather than as a declaration attribute. - while (auto *tt = qty->getAs()) { - if (tt->getDecl()->hasAttr()) - return true; - qty = tt->desugar(); - } - return false; -} - -/// Check if the given type is a valid base type to be used in access tags. -static bool isValidBaseType(clang::QualType qty) { - if (const clang::RecordType *tty = qty->getAs()) { - const clang::RecordDecl *rd = tty->getDecl()->getDefinition(); - // Incomplete types are not valid base access types. - if (!rd) - return false; - if (rd->hasFlexibleArrayMember()) - return false; - // rd can be struct, union, class, interface or enum. - // For now, we only handle struct and class. - if (rd->isStruct() || rd->isClass()) - return true; - } - return false; -} - cir::TBAAAttr CIRGenTBAA::getTypeInfo(clang::QualType qty) { - // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. - if (codeGenOpts.OptimizationLevel == 0 || codeGenOpts.RelaxedAliasing) { - return nullptr; - } - - // If the type has the may_alias attribute (even on a typedef), it is - // effectively in the general char alias class. - if (typeHasMayAlias(qty)) { - assert(!cir::MissingFeatures::tbaaMayAlias()); - return getChar(); - } - // We need this function to not fall back to returning the "omnipotent char" - // type node for aggregate and union types. Otherwise, any dereference of an - // aggregate will result into the may-alias access descriptor, meaning all - // subsequent accesses to direct and indirect members of that aggregate will - // be considered may-alias too. - // function. - if (isValidBaseType(qty)) { - // TODO(cir): support TBAA with struct - return tbaa_NYI(mlirContext); - } - - const clang::Type *ty = astContext.getCanonicalType(qty).getTypePtr(); - if (metadataCache.contains(ty)) { - return metadataCache[ty]; - } - - // Note that the following helper call is allowed to add new nodes to the - // cache, which invalidates all its previously obtained iterators. So we - // first generate the node for the type and then add that node to the - // cache. - auto typeNode = cir::TBAAScalarAttr::get(mlirContext, types.ConvertType(qty)); - return metadataCache[ty] = typeNode; + return tbaa_NYI(mlirContext); } TBAAAccessInfo CIRGenTBAA::getAccessInfo(clang::QualType accessType) { - // Pointee values may have incomplete types, but they shall never be - // dereferenced. - if (accessType->isIncompleteType()) { - assert(!cir::MissingFeatures::tbaaIncompleteType()); - return TBAAAccessInfo::getIncompleteInfo(); - } - - if (typeHasMayAlias(accessType)) { - assert(!cir::MissingFeatures::tbaaMayAlias()); - return TBAAAccessInfo::getMayAliasInfo(); - } - - uint64_t size = astContext.getTypeSizeInChars(accessType).getQuantity(); - return TBAAAccessInfo(getTypeInfo(accessType), size); + return TBAAAccessInfo(); } TBAAAccessInfo CIRGenTBAA::getVTablePtrAccessInfo(mlir::Type vtablePtrType) { - // TODO(cir): support vtable ptr - assert(!cir::MissingFeatures::tbaaVTablePtr()); return TBAAAccessInfo(); } mlir::ArrayAttr CIRGenTBAA::getTBAAStructInfo(clang::QualType qty) { - assert(!cir::MissingFeatures::tbaaStruct() && "tbaa.struct NYI"); - return mlir::ArrayAttr(); + return mlir::ArrayAttr::get(mlirContext, {}); } cir::TBAAAttr CIRGenTBAA::getBaseTypeInfo(clang::QualType qty) { return tbaa_NYI(mlirContext); } -cir::TBAAAttr CIRGenTBAA::getAccessTagInfo(TBAAAccessInfo tbaaInfo) { - assert(!tbaaInfo.isIncomplete() && - "Access to an object of an incomplete type!"); - - if (tbaaInfo.isMayAlias()) { - assert(!cir::MissingFeatures::tbaaMayAlias()); - tbaaInfo = TBAAAccessInfo(getChar(), tbaaInfo.size); - } - if (!tbaaInfo.accessType) { - return nullptr; - } - - if (!codeGenOpts.StructPathTBAA) - tbaaInfo = TBAAAccessInfo(tbaaInfo.accessType, tbaaInfo.size); - - if (!tbaaInfo.baseType) { - tbaaInfo.baseType = tbaaInfo.accessType; - assert(!tbaaInfo.offset && - "Nonzero offset for an access with no base type!"); - } - if (codeGenOpts.NewStructPathTBAA) { - llvm_unreachable("NYI"); - } - if (tbaaInfo.baseType == tbaaInfo.accessType) { - return tbaaInfo.accessType; - } - return tbaa_NYI(mlirContext); +mlir::ArrayAttr CIRGenTBAA::getAccessTagInfo(TBAAAccessInfo tbaaInfo) { + return mlir::ArrayAttr::get(mlirContext, {tbaa_NYI(mlirContext)}); } TBAAAccessInfo CIRGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo sourceInfo, TBAAAccessInfo targetInfo) { - assert(!cir::MissingFeatures::tbaaMergeTBAAInfo()); return TBAAAccessInfo(); } TBAAAccessInfo CIRGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo infoA, TBAAAccessInfo infoB) { - assert(!cir::MissingFeatures::tbaaMergeTBAAInfo()); return TBAAAccessInfo(); } TBAAAccessInfo CIRGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo destInfo, TBAAAccessInfo srcInfo) { - assert(!cir::MissingFeatures::tbaaMergeTBAAInfo()); return TBAAAccessInfo(); } diff --git a/clang/lib/CIR/CodeGen/CIRGenTBAA.h b/clang/lib/CIR/CodeGen/CIRGenTBAA.h index 03b9b75113c9..3f59a0e6538b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTBAA.h +++ b/clang/lib/CIR/CodeGen/CIRGenTBAA.h @@ -104,10 +104,6 @@ class CIRGenTBAA { [[maybe_unused]] const clang::CodeGenOptions &codeGenOpts; [[maybe_unused]] const clang::LangOptions &features; - llvm::DenseMap metadataCache; - - cir::TBAAAttr getChar(); - public: CIRGenTBAA(mlir::MLIRContext *mlirContext, clang::ASTContext &astContext, CIRGenTypes &types, mlir::ModuleOp moduleOp, @@ -133,7 +129,7 @@ class CIRGenTBAA { cir::TBAAAttr getBaseTypeInfo(clang::QualType qty); /// Get TBAA tag for a given memory access. - cir::TBAAAttr getAccessTagInfo(TBAAAccessInfo tbaaInfo); + mlir::ArrayAttr getAccessTagInfo(TBAAAccessInfo tbaaInfo); /// Get merged TBAA information for the purpose of type casts. TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo sourceInfo, diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 242afd4f00b8..1c5a6467f538 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -17,7 +17,6 @@ #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/Interfaces/CIRLoopOpInterface.h" #include "clang/CIR/MissingFeatures.h" -#include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/ErrorHandling.h" #include #include @@ -107,12 +106,12 @@ struct CIROpAsmDialectInterface : public OpAsmDialectInterface { os << dynCastInfoAttr.getAlias(); return AliasResult::FinalAlias; } - return TypeSwitch(attr) - .Case([&](auto attr) { - os << decltype(attr)::getMnemonic(); - return AliasResult::OverridableAlias; - }) - .Default([](Attribute) { return AliasResult::NoAlias; }); + if (auto tbaaAttr = mlir::dyn_cast(attr)) { + os << tbaaAttr.getMnemonic(); + return AliasResult::OverridableAlias; + } + + return AliasResult::NoAlias; } }; } // namespace diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp index bb99d53e0ad8..80963353a304 100644 --- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp @@ -151,7 +151,7 @@ DeletionKind cir::CopyOp::removeBlockingUses( if (loadsFrom(slot)) builder.create(getLoc(), reachingDefinition, getDst(), false, mlir::IntegerAttr{}, cir::MemOrderAttr(), - cir::TBAAAttr{}); + mlir::ArrayAttr{}); return DeletionKind::Delete; } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index d84eb724406a..c933035cd850 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -18,7 +18,6 @@ #include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h" #include "mlir/Dialect/DLTI/DLTI.h" #include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" #include "mlir/Dialect/LLVMIR/Transforms/Passes.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/Builders.h" @@ -42,9 +41,6 @@ #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Export.h" -#include "clang/CIR/Dialect/IR/CIRAttrs.h" -#include "clang/CIR/Dialect/IR/CIRDialect.h" -#include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/Dialect/Passes.h" #include "clang/CIR/LoweringHelpers.h" #include "clang/CIR/MissingFeatures.h" @@ -55,7 +51,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include "llvm/ADT/TypeSwitch.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/Casting.h" @@ -671,67 +666,6 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, llvm_unreachable("unhandled attribute type"); } -mlir::LLVM::TBAATypeDescriptorAttr -createScalarTypeNode(mlir::MLIRContext *ctx, llvm::StringRef typeName, - mlir::LLVM::TBAANodeAttr parent, int64_t offset) { - llvm::SmallVector members; - members.push_back(mlir::LLVM::TBAAMemberAttr::get(ctx, parent, offset)); - return mlir::LLVM::TBAATypeDescriptorAttr::get( - ctx, typeName, llvm::ArrayRef(members)); -} - -mlir::LLVM::TBAARootAttr getRoot(mlir::MLIRContext *ctx) { - return mlir::LLVM::TBAARootAttr::get( - ctx, mlir::StringAttr::get(ctx, "Simple C/C++ TBAA")); -} - -mlir::LLVM::TBAATypeDescriptorAttr getChar(mlir::MLIRContext *ctx) { - return createScalarTypeNode(ctx, "omnipotent char", getRoot(ctx), 0); -} - -// FIXME(cir): This should be moved and use tablegen approach -// see https://github.com/llvm/clangir/pull/1220#discussion_r1889187867 -StringRef getTypeName(mlir::Type type) { - return TypeSwitch(type) - .Case([](cir::IntType ty) { return ty.getTBAATypeName(); }) - .Case([](cir::SingleType) { return "float"; }) - .Case([](cir::DoubleType) { return "double"; }) - .Case([](cir::FP80Type) { return "f80"; }) - .Case([](cir::FP128Type) { return "f128"; }) - .Case( - [](cir::LongDoubleType) { return "long double"; }) - .Case([](cir::BoolType) { return "bool"; }) - .Case([](cir::PointerType) { return "any pointer"; }) - .Default([](auto ty) { - llvm::errs() << "unknown type: " << ty << "\n"; - return "unknown"; - }); -} - -mlir::LLVM::TBAATypeDescriptorAttr -lowerScalarType(mlir::MLIRContext *ctx, cir::TBAAScalarAttr scalarAttr) { - // special handle for omnipotent char - if (auto intTy = mlir::dyn_cast_or_null(scalarAttr.getType())) { - if (intTy.getWidth() == 1 || intTy.getWidth() == 8) { - return getChar(ctx); - } - } - auto name = getTypeName(scalarAttr.getType()); - return createScalarTypeNode(ctx, name, getChar(ctx), 0); -} - -mlir::ArrayAttr lowerCIRTBAAAttr(mlir::Attribute tbaa, - mlir::ConversionPatternRewriter &rewriter) { - auto *ctx = rewriter.getContext(); - if (auto scalarAttr = mlir::dyn_cast(tbaa)) { - auto accessType = lowerScalarType(ctx, scalarAttr); - auto tag = mlir::LLVM::TBAATagAttr::get(accessType, accessType, 0); - return mlir::ArrayAttr::get(ctx, {tag}); - } - assert(!cir::MissingFeatures::tbaaTagForStruct()); - return mlir::ArrayAttr(); -} - //===----------------------------------------------------------------------===// mlir::LLVM::Linkage convertLinkage(cir::GlobalLinkageKind linkage) { @@ -1578,14 +1512,10 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite( } // TODO: nontemporal, syncscope. - auto loadOp = rewriter.create( - op->getLoc(), llvmTy, adaptor.getAddr(), /* alignment */ alignment, + rewriter.replaceOpWithNewOp( + op, llvmTy, adaptor.getAddr(), /* alignment */ alignment, op.getIsVolatile(), /* nontemporal */ false, /* invariant */ false, /* invariantGroup */ invariant, ordering); - rewriter.replaceOp(op, loadOp); - if (auto tbaa = op.getTbaaAttr()) { - loadOp.setTBAATags(lowerCIRTBAAAttr(tbaa, rewriter)); - } return mlir::LogicalResult::success(); } @@ -1617,14 +1547,9 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite( } // TODO: nontemporal, syncscope. - auto storeOp = rewriter.create( - op->getLoc(), adaptor.getValue(), adaptor.getAddr(), alignment, - op.getIsVolatile(), + rewriter.replaceOpWithNewOp( + op, adaptor.getValue(), adaptor.getAddr(), alignment, op.getIsVolatile(), /* nontemporal */ false, /* invariantGroup */ invariant, ordering); - rewriter.replaceOp(op, storeOp); - if (auto tbaa = op.getTbaaAttr()) { - storeOp.setTBAATags(lowerCIRTBAAAttr(tbaa, rewriter)); - } return mlir::LogicalResult::success(); } diff --git a/clang/test/CIR/CodeGen/const-alloca.cpp b/clang/test/CIR/CodeGen/const-alloca.cpp index 7cc9a5b57517..9247b2692474 100644 --- a/clang/test/CIR/CodeGen/const-alloca.cpp +++ b/clang/test/CIR/CodeGen/const-alloca.cpp @@ -66,8 +66,8 @@ int local_const_load_store() { // LLVM-LABEL: @_Z22local_const_load_storev // LLVM: %[[#INIT:]] = call i32 @_Z11produce_intv() -// LLVM-NEXT: store i32 %[[#INIT]], ptr %[[#SLOT:]], align 4, !tbaa !{{.*}}, !invariant.group !{{.+}} -// LLVM-NEXT: %{{.+}} = load i32, ptr %[[#SLOT]], align 4, !tbaa !{{.*}}, !invariant.group !{{.+}} +// LLVM-NEXT: store i32 %[[#INIT]], ptr %[[#SLOT:]], align 4, !invariant.group !{{.+}} +// LLVM-NEXT: %{{.+}} = load i32, ptr %[[#SLOT]], align 4, !invariant.group !{{.+}} // LLVM: } int local_const_optimize() { @@ -80,7 +80,7 @@ int local_const_optimize() { // LLVM-LABEL: @_Z20local_const_optimizev() // LLVM-NEXT: %[[#slot:]] = alloca i32, align 4 // LLVM-NEXT: %[[#init:]] = tail call i32 @_Z11produce_intv() -// LLVM-NEXT: store i32 %[[#init]], ptr %[[#slot]], align 4, !tbaa !{{.*}}, !invariant.group !{{.+}} +// LLVM-NEXT: store i32 %[[#init]], ptr %[[#slot]], align 4, !invariant.group !{{.+}} // LLVM-NEXT: call void @_Z8blackboxRKi(ptr nonnull %[[#slot]]) // LLVM-NEXT: call void @_Z8blackboxRKi(ptr nonnull %[[#slot]]) // LLVM-NEXT: ret i32 %[[#init]] diff --git a/clang/test/CIR/CodeGen/tbaa-scalar.c b/clang/test/CIR/CodeGen/tbaa-scalar.c deleted file mode 100644 index b2f893b4f4ac..000000000000 --- a/clang/test/CIR/CodeGen/tbaa-scalar.c +++ /dev/null @@ -1,148 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -O1 -// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O1 -// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O1 -relaxed-aliasing -// RUN: FileCheck --check-prefix=NO-TBAA --input-file=%t.ll %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O0 -// RUN: FileCheck --check-prefix=NO-TBAA --input-file=%t.ll %s - -// NO-TBAA-NOT: !tbaa - -// CIR: #tbaa[[FLOAT_PTR:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[FLOAT:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[DOUBLE_PTR:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[DOUBLE:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[LONG_DOUBLE_PTR:.*]] = #cir.tbaa_scalar>> -// CIR: #tbaa[[LONG_DOUBLE:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[INT:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[LONG:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[CHAR:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[INT_PTR:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[LONG_PTR:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[CHAR_PTR:.*]] = #cir.tbaa_scalar> - -void test_int_and_float(int *a, float *b) { - // CIR-LABEL: cir.func @test_int_and_float - // CIR: cir.scope - // CIR: %[[TMP1:.*]] = cir.load deref %{{.*}} : !cir.ptr>, !cir.ptr tbaa(#tbaa[[INT_PTR]]) - // CIR: %[[TMP2:.*]] = cir.load %[[TMP1]] : !cir.ptr, !s32i tbaa(#tbaa[[INT]]) - // CIR: cir.if - // CIR: %[[C2:.*]] = cir.const #cir.fp<2 - // CIR: %[[TMP3:.*]] = cir.load deref %[[ARG_b:.*]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[FLOAT_PTR]]) - // CIR: cir.store %[[C2]], %[[TMP3]] : !cir.float, !cir.ptr tbaa(#tbaa[[FLOAT]]) - // CIR: else - // CIR: %[[C3:.*]] = cir.const #cir.fp<3 - // CIR: %[[TMP4:.*]] = cir.load deref %[[ARG_b]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[FLOAT_PTR]]) - // CIR: cir.store %[[C3]], %[[TMP4]] : !cir.float, !cir.ptr tbaa(#tbaa[[FLOAT]]) - - // LLVM-LABEL: void @test_int_and_float - // LLVM: %[[ARG_a:.*]] = load i32, ptr %{{.*}}, align 4, !tbaa ![[TBAA_INT:.*]] - // LLVM: %[[COND:.*]] = icmp eq i32 %[[ARG_a]], 1 - // LLVM: %[[RET:.*]] = select i1 %[[COND]], float 2.000000e+00, float 3.000000e+00 - // LLVM: store float %[[RET]], ptr %{{.*}}, align 4, !tbaa ![[TBAA_FLOAT:.*]] - // LLVM: ret void - if (*a == 1) { - *b = 2.0f; - } else { - *b = 3.0f; - } -} - -void test_long_and_double(long *a, double *b) { - // CIR-LABEL: cir.func @test_long_and_double - // CIR: cir.scope - // CIR: %[[TMP1:.*]] = cir.load deref %{{.*}} : !cir.ptr>, !cir.ptr tbaa(#tbaa[[LONG_PTR]]) - // CIR: %[[TMP2:.*]] = cir.load %[[TMP1]] : !cir.ptr, !s64i tbaa(#tbaa[[LONG]]) - // CIR: cir.if - // CIR: %[[C2:.*]] = cir.const #cir.fp<2 - // CIR: %[[TMP3:.*]] = cir.load deref %[[ARG_b:.*]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[DOUBLE_PTR]]) - // CIR: cir.store %[[C2]], %[[TMP3]] : !cir.double, !cir.ptr tbaa(#tbaa[[DOUBLE]]) - // CIR: else - // CIR: %[[C3:.*]] = cir.const #cir.fp<3 - // CIR: %[[TMP4:.*]] = cir.load deref %[[ARG_b]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[DOUBLE_PTR]]) - // CIR: cir.store %[[C3]], %[[TMP4]] : !cir.double, !cir.ptr tbaa(#tbaa[[DOUBLE]]) - - // LLVM-LABEL: void @test_long_and_double - // LLVM: %[[ARG_a:.*]] = load i64, ptr %{{.*}}, align 8, !tbaa ![[TBAA_LONG:.*]] - // LLVM: %[[COND:.*]] = icmp eq i64 %[[ARG_a]], 1 - // LLVM: %[[RET:.*]] = select i1 %[[COND]], double 2.000000e+00, double 3.000000e+00 - // LLVM: store double %[[RET]], ptr %{{.*}}, align 8, !tbaa ![[TBAA_DOUBLE:.*]] - // LLVM: ret void - if (*a == 1L) { - *b = 2.0; - } else { - *b = 3.0; - } -} -void test_long_long_and_long_double(long long *a, long double *b) { - // CIR-LABEL: cir.func @test_long_long_and_long_double - // CIR: cir.scope - // CIR: %[[TMP1:.*]] = cir.load deref %{{.*}} : !cir.ptr>, !cir.ptr tbaa(#tbaa[[LONG_PTR]]) - // CIR: %[[TMP2:.*]] = cir.load %[[TMP1]] : !cir.ptr, !s64i tbaa(#tbaa[[LONG]]) - // CIR: cir.if - // CIR: %[[C2:.*]] = cir.const #cir.fp<2 - // CIR: %[[TMP3:.*]] = cir.load deref %[[ARG_b:.*]] : !cir.ptr>>, !cir.ptr> tbaa(#tbaa[[LONG_DOUBLE_PTR]]) - // CIR: cir.store %[[C2]], %[[TMP3]] : !cir.long_double, !cir.ptr> tbaa(#tbaa[[LONG_DOUBLE]]) - // CIR: else - // CIR: %[[C3:.*]] = cir.const #cir.fp<3 - // CIR: %[[TMP4:.*]] = cir.load deref %[[ARG_b]] : !cir.ptr>>, !cir.ptr> tbaa(#tbaa[[LONG_DOUBLE_PTR]]) - // CIR: cir.store %[[C3]], %[[TMP4]] : !cir.long_double, !cir.ptr> tbaa(#tbaa[[LONG_DOUBLE]]) - - // LLVM-LABEL: void @test_long_long_and_long_double - // LLVM: %[[ARG_a:.*]] = load i64, ptr %{{.*}}, align 8, !tbaa ![[TBAA_LONG_LONG:.*]] - // LLVM: %[[COND:.*]] = icmp eq i64 %[[ARG_a]], 1 - // LLVM: %[[RET:.*]] = select i1 %[[COND]], x86_fp80 0xK40008000000000000000, x86_fp80 0xK4000C000000000000000 - // LLVM: store x86_fp80 %[[RET]], ptr %{{.*}}, align 16, !tbaa ![[TBAA_LONG_DOUBLE:.*]] - // LLVM: ret void - if (*a == 1L) { - *b = 2.0L; - } else { - *b = 3.0L; - } -} - -void test_char(char *a, char* b) { - // CIR-LABEL: cir.func @test_char - // CIR: cir.scope - // CIR: %[[TMP1:.*]] = cir.load deref %{{.*}} : !cir.ptr>, !cir.ptr tbaa(#tbaa[[CHAR_PTR]]) - // CIR: %[[TMP2:.*]] = cir.load %[[TMP1]] : !cir.ptr, !s8i tbaa(#tbaa[[CHAR]]) - // CIR: cir.if - // CIR: %[[C2:.*]] = cir.const #cir.int<98> : !s32i - // CIR: %[[C2_CHAR:.*]] = cir.cast(integral, %[[C2]] : !s32i), !s8i - // CIR: %[[TMP3:.*]] = cir.load deref %[[ARG_b:.*]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[CHAR_PTR]]) - // CIR: cir.store %[[C2_CHAR]], %[[TMP3]] : !s8i, !cir.ptr tbaa(#tbaa[[CHAR]]) - // CIR: else - // CIR: %[[C3:.*]] = cir.const #cir.int<0> : !s32i - // CIR: %[[C3_CHAR:.*]] = cir.cast(integral, %[[C3]] : !s32i), !s8i - // CIR: %[[TMP4:.*]] = cir.load deref %[[ARG_b]] : !cir.ptr>, !cir.ptr tbaa(#tbaa[[CHAR_PTR]]) - // CIR: cir.store %[[C3_CHAR]], %[[TMP4]] : !s8i, !cir.ptr tbaa(#tbaa[[CHAR]]) - - - // LLVM-LABEL: void @test_char - // LLVM: %[[ARG_a:.*]] = load i8, ptr %{{.*}}, align 1, !tbaa ![[TBAA_CHAR:.*]] - // LLVM: %[[COND:.*]] = icmp eq i8 %[[ARG_a]], 97 - // LLVM: %[[RET:.*]] = select i1 %[[COND]], i8 98, i8 0 - // LLVM: store i8 %[[RET]], ptr %{{.*}}, align 1, !tbaa ![[TBAA_CHAR]] - // LLVM: ret void - if (*a == 'a') { - *b = 'b'; - } - else { - *b = '\0'; - } -} - -// LLVM: ![[TBAA_INT]] = !{![[TBAA_INT_PARENT:.*]], ![[TBAA_INT_PARENT]], i64 0} -// LLVM: ![[TBAA_INT_PARENT]] = !{!"int", ![[CHAR:.*]], i64 0} -// LLVM: ![[CHAR]] = !{!"omnipotent char", ![[ROOT:.*]], i64 0} -// LLVM: ![[ROOT]] = !{!"Simple C/C++ TBAA"} -// LLVM: ![[TBAA_FLOAT]] = !{![[TBAA_FLOAT_PARENT:.*]], ![[TBAA_FLOAT_PARENT]], i64 0} -// LLVM: ![[TBAA_FLOAT_PARENT]] = !{!"float", ![[CHAR]], i64 0} -// LLVM: ![[TBAA_LONG]] = !{![[TBAA_LONG_PARENT:.*]], ![[TBAA_LONG_PARENT]], i64 0} -// LLVM: ![[TBAA_LONG_PARENT]] = !{!"long", ![[CHAR]], i64 0} -// LLVM: ![[TBAA_DOUBLE]] = !{![[TBAA_DOUBLE_PARENT:.*]], ![[TBAA_DOUBLE_PARENT]], i64 0} -// LLVM: ![[TBAA_DOUBLE_PARENT]] = !{!"double", ![[CHAR]], i64 0} -// LLVM: ![[TBAA_LONG_DOUBLE]] = !{![[TBAA_LONG_DOUBLE_PARENT:.*]], ![[TBAA_LONG_DOUBLE_PARENT]], i64 0} -// LLVM: ![[TBAA_LONG_DOUBLE_PARENT]] = !{!"long double", ![[CHAR]], i64 0} -// LLVM: ![[TBAA_CHAR]] = !{![[CHAR]], ![[CHAR]], i64 0} diff --git a/clang/test/CIR/CodeGen/tbaa-struct.cpp b/clang/test/CIR/CodeGen/tbaa-struct.cpp deleted file mode 100644 index 84c49df6b455..000000000000 --- a/clang/test/CIR/CodeGen/tbaa-struct.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -O1 -// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s - -// CIR: #tbaa[[tbaa_NYI:.*]] = #cir.tbaa -// CIR: #tbaa[[INT:.*]] = #cir.tbaa_scalar -// CIR: #tbaa[[INT_PTR:.*]] = #cir.tbaa_scalar> -// CIR: #tbaa[[StructA_PTR:.*]] = #cir.tbaa_scalar> - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef struct -{ - uint16_t f16; - uint32_t f32; - uint16_t f16_2; - uint32_t f32_2; -} StructA; - -uint32_t g(uint32_t *s, StructA *A) { - // CIR-LABEL: cir.func @_Z1g - // CIR: %[[INT_1:.*]] = cir.const #cir.int<1> : !s32i - // CIR: %[[UINT_1:.*]] = cir.cast(integral, %[[INT_1]] : !s32i), !u32i - // CIR: cir.store %[[UINT_1]], %{{.*}} : !u32i, !cir.ptr tbaa(#tbaa[[INT]]) - // CIR: %[[INT_4:.*]] = cir.const #cir.int<4> : !s32i - // CIR: %[[UINT_4:.*]] = cir.cast(integral, %[[INT_4]] : !s32i), !u32i - // CIR: %[[pointer_to_StructA:.*]] = cir.load %{{.*}} : !cir.ptr>, !cir.ptr tbaa(#tbaa[[StructA_PTR]]) - // CIR: %[[A_f32:.*]] = cir.get_member %[[pointer_to_StructA]][1] {name = "f32"} : !cir.ptr -> !cir.ptr - // CIR: cir.store %[[UINT_4]], %[[A_f32]] : !u32i, !cir.ptr tbaa(#tbaa[[tbaa_NYI]]) - - *s = 1; - A->f32 = 4; - return *s; -} diff --git a/clang/test/CIR/CodeGen/tbaa-vptr.cpp b/clang/test/CIR/CodeGen/tbaa-vptr.cpp deleted file mode 100644 index dbe28be626a2..000000000000 --- a/clang/test/CIR/CodeGen/tbaa-vptr.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -O1 -// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s - -// CIR-NOT: #tbaa - -struct Member { - ~Member(); -}; - -struct A { - virtual ~A(); -}; - -struct B : A { - Member m; - virtual ~B(); -}; -B::~B() { } diff --git a/clang/test/CIR/CodeGen/tbaa.c b/clang/test/CIR/CodeGen/tbaa.c new file mode 100644 index 000000000000..43cdde47ecb7 --- /dev/null +++ b/clang/test/CIR/CodeGen/tbaa.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -O1 +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s + +// CIR: #tbaa[[TBAA_NO:.*]] = #cir.tbaa +void f(int *a, float *b) { + // CIR: cir.scope + // CIR: %[[TMP1:.*]] = cir.load deref %{{.*}} : !cir.ptr>, !cir.ptr tbaa([#tbaa[[TBAA_NO]]]) + // CIR: %[[TMP2:.*]] = cir.load %[[TMP1]] : !cir.ptr, !s32i tbaa([#tbaa[[TBAA_NO]]]) + // CIR: cir.if + // CIR: %[[C2:.*]] = cir.const #cir.fp<2 + // CIR: %[[TMP3:.*]] = cir.load deref %[[ARG_b:.*]] : !cir.ptr>, !cir.ptr tbaa([#tbaa[[TBAA_NO]]]) + // CIR: cir.store %[[C2]], %[[TMP3]] : !cir.float, !cir.ptr tbaa([#tbaa[[TBAA_NO]]]) + // CIR: else + // CIR: %[[C3:.*]] = cir.const #cir.fp<3 + // CIR: %[[TMP4:.*]] = cir.load deref %[[ARG_b]] : !cir.ptr>, !cir.ptr tbaa([#tbaa[[TBAA_NO]]]) + // CIR: cir.store %[[C3]], %[[TMP4]] : !cir.float, !cir.ptr tbaa([#tbaa[[TBAA_NO]]]) + if (*a == 1) { + *b = 2.0f; + } else { + *b = 3.0f; + } +}