https://github.com/RiverDave created https://github.com/llvm/llvm-project/pull/179073
None >From 9ddd795e75b8e4ca6fa1559eab17d8e8c9f3a542 Mon Sep 17 00:00:00 2001 From: David Rivera <[email protected]> Date: Sat, 31 Jan 2026 17:32:31 -0500 Subject: [PATCH] [CIR] Implement MemorySpaceAttrInterface for lang and target specific AS attributes --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 20 ++-- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 2 +- clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 14 ++- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 10 +- clang/lib/CIR/CodeGen/Address.h | 3 +- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 2 +- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 16 +-- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 5 +- clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 5 +- clang/lib/CIR/CodeGen/TargetInfo.cpp | 6 +- clang/lib/CIR/CodeGen/TargetInfo.h | 11 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 104 +++++++++--------- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 23 +++- clang/test/CIR/IR/address-space.cir | 41 +++++++ clang/test/CIR/IR/invalid-addrspace.cir | 32 +++++- 15 files changed, 192 insertions(+), 102 deletions(-) create mode 100644 clang/test/CIR/IR/address-space.cir diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 2aaae86240cf2..de32aa227174d 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -153,29 +153,27 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return cir::PointerType::get(ty); } - cir::PointerType getPointerTo(mlir::Type ty, cir::TargetAddressSpaceAttr as) { + + cir::PointerType getPointerTo(mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface as) { + if (!as) + return cir::PointerType::get(ty); return cir::PointerType::get(ty, as); } cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) { - if (langAS == clang::LangAS::Default) // Default address space. + if (langAS == clang::LangAS::Default) return getPointerTo(ty); - if (clang::isTargetAddressSpace(langAS)) { - unsigned addrSpace = clang::toTargetAddressSpace(langAS); - auto asAttr = cir::TargetAddressSpaceAttr::get( - getContext(), getUI32IntegerAttr(addrSpace)); - return getPointerTo(ty, asAttr); - } - - llvm_unreachable("language-specific address spaces NYI"); + mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr = + cir::toCIRAddressSpaceAttr(getContext(), langAS); + return getPointerTo(ty, addrSpaceAttr); } cir::PointerType getVoidPtrTy(clang::LangAS langAS = clang::LangAS::Default) { return getPointerTo(cir::VoidType::get(getContext()), langAS); } - cir::PointerType getVoidPtrTy(cir::TargetAddressSpaceAttr as) { + cir::PointerType getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface as) { return getPointerTo(cir::VoidType::get(getContext()), as); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 4fbab2e83663d..0ab45f776f822 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -838,7 +838,7 @@ def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace", ``` }]; - let parameters = (ins "mlir::IntegerAttr":$value); + let parameters = (ins "unsigned":$value); let assemblyFormat = "`<` `target` `<` $value `>` `>`"; } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 16c48ba4fb4e9..ff0abfd01caba 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -47,12 +47,18 @@ bool isSized(mlir::Type ty); cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS); -cir::TargetAddressSpaceAttr toCIRTargetAddressSpace(mlir::MLIRContext &context, - clang::LangAS langAS); - -bool isMatchingAddressSpace(cir::TargetAddressSpaceAttr cirAS, +// Compare a CIR memory space attribute with a Clang LangAS. +bool isMatchingAddressSpace(mlir::MLIRContext &ctx, + mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as); +/// Convert an AST LangAS to the appropriate CIR address space attribute interface. +mlir::ptr::MemorySpaceAttrInterface +toCIRAddressSpaceAttr(mlir::MLIRContext *ctx, clang::LangAS langAS); + +bool isSupportedCIRMemorySpaceAttr( + mlir::ptr::MemorySpaceAttrInterface memorySpace); + } // namespace cir //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 5ba7726e9b1a6..a940047f38acf 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -252,19 +252,19 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [ let parameters = (ins "mlir::Type":$pointee, OptionalParameter< - "cir::TargetAddressSpaceAttr">:$addrSpace + "mlir::ptr::MemorySpaceAttrInterface">:$addrSpace ); let skipDefaultBuilders = 1; let builders = [ TypeBuilderWithInferredContext<(ins "mlir::Type":$pointee, - CArg<"cir::TargetAddressSpaceAttr", "nullptr">:$addrSpace), [{ + CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace), [{ return $_get(pointee.getContext(), pointee, addrSpace); }]>, TypeBuilder<(ins "mlir::Type":$pointee, - CArg<"cir::TargetAddressSpaceAttr", "nullptr">:$addrSpace), [{ + CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace), [{ return $_get($_ctxt, pointee, addrSpace); }]> ]; @@ -272,7 +272,7 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [ let assemblyFormat = [{ `<` $pointee - ( `,` ` ` custom<TargetAddressSpace>($addrSpace)^ )? + ( `,` ` ` custom<AddressSpaceValue>($addrSpace)^ )? `>` }]; @@ -303,6 +303,8 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [ return false; } }]; + + let genVerifyDecl = 1; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/Address.h b/clang/lib/CIR/CodeGen/Address.h index f32cde957cd5c..b459ec948c2c4 100644 --- a/clang/lib/CIR/CodeGen/Address.h +++ b/clang/lib/CIR/CodeGen/Address.h @@ -14,6 +14,7 @@ #ifndef CLANG_LIB_CIR_ADDRESS_H #define CLANG_LIB_CIR_ADDRESS_H +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/Value.h" #include "clang/AST/CharUnits.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" @@ -127,7 +128,7 @@ class Address { return elementType; } - cir::TargetAddressSpaceAttr getAddressSpace() const { + mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const { auto ptrTy = mlir::dyn_cast<cir::PointerType>(getType()); return ptrTy.getAddrSpace(); } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 0e5a5b531df78..474d2c0d00c8f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -338,7 +338,7 @@ static RValue emitBuiltinAlloca(CIRGenFunction &cgf, const CallExpr *e, // builtin / dynamic alloca we have to handle it here. if (!cir::isMatchingAddressSpace( - cgf.getCIRAllocaAddressSpace(), + cgf.getMLIRContext(), cgf.getCIRAllocaAddressSpace(), e->getType()->getPointeeType().getAddressSpace())) { cgf.cgm.errorNYI(e->getSourceRange(), "Non-default address space for alloca"); diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 504f18e1a9f31..ce0e62164029a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -15,6 +15,7 @@ #include "CIRGenFunction.h" #include "CIRGenModule.h" #include "CIRGenValue.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Value.h" #include "clang/AST/Attr.h" @@ -1437,9 +1438,9 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { QualType destTy = getContext().getPointerType(e->getType()); clang::LangAS srcLangAS = e->getSubExpr()->getType().getAddressSpace(); - cir::TargetAddressSpaceAttr srcAS; + mlir::ptr::MemorySpaceAttrInterface srcAS; if (clang::isTargetAddressSpace(srcLangAS)) - srcAS = cir::toCIRTargetAddressSpace(getMLIRContext(), srcLangAS); + srcAS = cir::toCIRAddressSpaceAttr(&getMLIRContext(), srcLangAS); else cgm.errorNYI( e->getSourceRange(), @@ -2486,15 +2487,8 @@ Address CIRGenFunction::createTempAlloca(mlir::Type ty, CharUnits align, // in C++ the auto variables are in the default address space. Therefore // cast alloca to the default address space when necessary. - LangAS allocaAS = alloca.getAddressSpace() - ? clang::getLangASFromTargetAS( - alloca.getAddressSpace().getValue().getUInt()) - : clang::LangAS::Default; - LangAS dstTyAS = clang::LangAS::Default; - if (getCIRAllocaAddressSpace()) { - dstTyAS = clang::getLangASFromTargetAS( - getCIRAllocaAddressSpace().getValue().getUInt()); - } + mlir::ptr::MemorySpaceAttrInterface allocaAS = alloca.getAddressSpace(); + mlir::ptr::MemorySpaceAttrInterface dstTyAS = getCIRAllocaAddressSpace(); if (dstTyAS != allocaAS) { getTargetHooks().performAddrSpaceCast(*this, v, getCIRAllocaAddressSpace(), diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 2af210bed98ff..62d9117562e8b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -19,6 +19,7 @@ #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/Location.h" #include "mlir/IR/Value.h" @@ -2143,9 +2144,9 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) { srcTy = srcTy->getPointeeType(); clang::LangAS srcLangAS = srcTy.getAddressSpace(); - cir::TargetAddressSpaceAttr subExprAS; + mlir::ptr::MemorySpaceAttrInterface subExprAS; if (clang::isTargetAddressSpace(srcLangAS)) - subExprAS = cir::toCIRTargetAddressSpace(cgf.getMLIRContext(), srcLangAS); + subExprAS = cir::toCIRAddressSpaceAttr(&cgf.getMLIRContext(), srcLangAS); else cgf.cgm.errorNYI(subExpr->getSourceRange(), "non-target address space conversion"); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h index 0f63e91f45564..4f3c319816e3a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H #define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "clang/AST/CharUnits.h" #include "clang/Basic/AddressSpaces.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" @@ -80,7 +81,7 @@ struct CIRGenTypeCache { unsigned char SizeAlignInBytes; }; - cir::TargetAddressSpaceAttr cirAllocaAddressSpace; + mlir::ptr::MemorySpaceAttrInterface cirAllocaAddressSpace; clang::CharUnits getSizeSize() const { return clang::CharUnits::fromQuantity(SizeSizeInBytes); @@ -93,7 +94,7 @@ struct CIRGenTypeCache { return clang::CharUnits::fromQuantity(PointerAlignInBytes); } - cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const { + mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const { return cirAllocaAddressSpace; } }; diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp index 377c532e492d9..275ad03cfd61f 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.cpp +++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp @@ -1,6 +1,7 @@ #include "TargetInfo.h" #include "ABIInfo.h" #include "CIRGenFunction.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" @@ -73,8 +74,9 @@ bool TargetCIRGenInfo::isNoProtoCallVariadic( } mlir::Value TargetCIRGenInfo::performAddrSpaceCast( - CIRGenFunction &cgf, mlir::Value v, cir::TargetAddressSpaceAttr srcAddr, - mlir::Type destTy, bool isNonNull) const { + CIRGenFunction &cgf, mlir::Value v, + mlir::ptr::MemorySpaceAttrInterface srcAddr, mlir::Type destTy, + bool isNonNull) const { // Since target may map different address spaces in AST to the same address // space, an address space conversion may end up as a bitcast. if (cir::GlobalOp globalOp = v.getDefiningOp<cir::GlobalOp>()) diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h index 9535ba94fb08b..25bde654810ad 100644 --- a/clang/lib/CIR/CodeGen/TargetInfo.h +++ b/clang/lib/CIR/CodeGen/TargetInfo.h @@ -16,6 +16,7 @@ #include "ABIInfo.h" #include "CIRGenTypes.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "clang/Basic/AddressSpaces.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" @@ -48,7 +49,7 @@ class TargetCIRGenInfo { const ABIInfo &getABIInfo() const { return *info; } /// Get the address space for alloca. - virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const { + virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const { return {}; } /// Perform address space cast of an expression of pointer type. @@ -56,10 +57,10 @@ class TargetCIRGenInfo { /// \param DestTy is the destination pointer type. /// \param srcAS is theaddress space of \p V. /// \param IsNonNull is the flag indicating \p V is known to be non null. - virtual mlir::Value performAddrSpaceCast(CIRGenFunction &cgf, mlir::Value v, - cir::TargetAddressSpaceAttr srcAddr, - mlir::Type destTy, - bool isNonNull = false) const; + virtual mlir::Value + performAddrSpaceCast(CIRGenFunction &cgf, mlir::Value v, + mlir::ptr::MemorySpaceAttrInterface srcAS, + mlir::Type destTy, bool isNonNull = false) const; /// Determine whether a call to an unprototyped functions under /// the given calling convention should use the variadic diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 8d97a8d5c88cd..8a8ada3d9ec20 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -12,12 +12,15 @@ #include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/IR/MLIRContext.h" +#include "mlir/Support/LLVM.h" #include "clang/Basic/AddressSpaces.h" #include "clang/CIR/Dialect/IR/CIRAttrs.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" #include "clang/CIR/Dialect/IR/CIRTypesDetails.h" #include "clang/CIR/MissingFeatures.h" #include "llvm/ADT/APInt.h" @@ -313,14 +316,13 @@ Type RecordType::getLargestMember(const ::mlir::DataLayout &dataLayout) const { auto endIt = getPadded() ? std::prev(members.end()) : members.end(); if (endIt == members.begin()) return {}; - return *std::max_element( - members.begin(), endIt, [&](Type lhs, Type rhs) { - return dataLayout.getTypeABIAlignment(lhs) < - dataLayout.getTypeABIAlignment(rhs) || - (dataLayout.getTypeABIAlignment(lhs) == - dataLayout.getTypeABIAlignment(rhs) && - dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs)); - }); + return *std::max_element(members.begin(), endIt, [&](Type lhs, Type rhs) { + return dataLayout.getTypeABIAlignment(lhs) < + dataLayout.getTypeABIAlignment(rhs) || + (dataLayout.getTypeABIAlignment(lhs) == + dataLayout.getTypeABIAlignment(rhs) && + dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs)); + }); } bool RecordType::isLayoutIdentical(const RecordType &other) { @@ -941,6 +943,12 @@ void cir::VectorType::print(mlir::AsmPrinter &odsPrinter) const { // AddressSpace definitions //===----------------------------------------------------------------------===// +bool cir::isSupportedCIRMemorySpaceAttr( + mlir::ptr::MemorySpaceAttrInterface memorySpace) { + return mlir::isa<cir::LangAddressSpaceAttr, cir::TargetAddressSpaceAttr>( + memorySpace); +} + cir::LangAddressSpace cir::toCIRLangAddressSpace(clang::LangAS langAS) { using clang::LangAS; switch (langAS) { @@ -999,8 +1007,7 @@ parseAddressSpaceValue(mlir::AsmParser &p, if (p.parseRParen()) return p.emitError(loc, "expected ')'"); - attr = cir::TargetAddressSpaceAttr::get( - p.getContext(), p.getBuilder().getUI32IntegerAttr(val)); + attr = cir::TargetAddressSpaceAttr::get(p.getContext(), val); return mlir::success(); } @@ -1012,7 +1019,7 @@ parseAddressSpaceValue(mlir::AsmParser &p, mlir::FailureOr<cir::LangAddressSpace> result = mlir::FieldParser<cir::LangAddressSpace>::parse(p); if (mlir::failed(result)) - return p.emitError(loc, "expected language address space keyword"); + return mlir::failure(); if (p.parseRParen()) return p.emitError(loc, "expected ')'"); @@ -1021,6 +1028,12 @@ parseAddressSpaceValue(mlir::AsmParser &p, return mlir::success(); } + llvm::StringRef keyword; + if (p.parseOptionalKeyword(&keyword).succeeded()) + return p.emitError(loc, "unknown address space specifier '") + << keyword << "'; expected 'target_address_space' or " + << "'lang_address_space'"; + return mlir::success(); } @@ -1043,55 +1056,42 @@ void printAddressSpaceValue(mlir::AsmPrinter &p, llvm_unreachable("unexpected address-space attribute kind"); } -cir::TargetAddressSpaceAttr -cir::toCIRTargetAddressSpace(mlir::MLIRContext &context, clang::LangAS langAS) { - return cir::TargetAddressSpaceAttr::get( - &context, - IntegerAttr::get(&context, - llvm::APSInt(clang::toTargetAddressSpace(langAS)))); -} +mlir::ptr::MemorySpaceAttrInterface +cir::toCIRAddressSpaceAttr(mlir::MLIRContext *ctx, clang::LangAS langAS) { + using clang::LangAS; -bool cir::isMatchingAddressSpace(cir::TargetAddressSpaceAttr cirAS, - clang::LangAS as) { - // If there is no CIR target attr, consider it "default" and only match - // when the AST address space is LangAS::Default. - if (!cirAS) - return as == clang::LangAS::Default; + if (langAS == LangAS::Default) + return {}; // Default address space is represented as an empty attribute. - if (!isTargetAddressSpace(as)) - return false; + if (clang::isTargetAddressSpace(langAS)) { + unsigned targetAS = clang::toTargetAddressSpace(langAS); + return cir::TargetAddressSpaceAttr::get(ctx, targetAS); + } - return cirAS.getValue().getUInt() == toTargetAddressSpace(as); + return cir::LangAddressSpaceAttr::get(ctx, toCIRLangAddressSpace(langAS)); } -mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, - cir::TargetAddressSpaceAttr &attr) { - if (failed(p.parseKeyword("target_address_space"))) - return mlir::failure(); - - if (failed(p.parseLParen())) - return mlir::failure(); - - int32_t targetValue; - if (failed(p.parseInteger(targetValue))) - return p.emitError(p.getCurrentLocation(), - "expected integer address space value"); +bool cir::isMatchingAddressSpace(mlir::MLIRContext &ctx, + mlir::ptr::MemorySpaceAttrInterface cirAS, + clang::LangAS as) { + return cir::toCIRAddressSpaceAttr(&ctx, as) == cirAS; +} - if (failed(p.parseRParen())) - return p.emitError(p.getCurrentLocation(), - "expected ')' after address space value"); +//===----------------------------------------------------------------------===// +// PointerType Definitions +//===----------------------------------------------------------------------===// - mlir::MLIRContext *context = p.getBuilder().getContext(); - attr = cir::TargetAddressSpaceAttr::get( - context, p.getBuilder().getUI32IntegerAttr(targetValue)); - return mlir::success(); -} +mlir::LogicalResult cir::PointerType::verify( + llvm::function_ref<mlir::InFlightDiagnostic()> emitError, + mlir::Type pointee, mlir::ptr::MemorySpaceAttrInterface addrSpace) { + if (addrSpace) { + if (!isSupportedCIRMemorySpaceAttr(addrSpace)) { + return emitError() << "unsupported address space attribute; expected " + "'target_address_space' or 'lang_address_space'"; + } + } -// The custom printer for the `addrspace` parameter in `!cir.ptr`. -// in the format of `target_address_space(N)`. -void printTargetAddressSpace(mlir::AsmPrinter &p, - cir::TargetAddressSpaceAttr attr) { - p << "target_address_space(" << attr.getValue().getUInt() << ")"; + return success(); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index a774b0dcc6ba8..584d163e15073 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -21,12 +21,14 @@ #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/LLVMIR/LLVMTypes.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinDialect.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Types.h" #include "mlir/Pass/Pass.h" #include "mlir/Pass/PassManager.h" +#include "mlir/Support/LLVM.h" #include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Export.h" @@ -40,6 +42,7 @@ #include "clang/CIR/Passes.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/IR/Module.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TimeProfiler.h" @@ -2953,14 +2956,28 @@ std::unique_ptr<cir::LowerModule> prepareLowerModule(mlir::ModuleOp module) { return {}; return cir::createLowerModule(module, rewriter); } +static unsigned +getNumericASFromCIRAS(mlir::ptr::MemorySpaceAttrInterface asAttr, + [[maybe_unused]] cir::LowerModule *lowerModule) { + if (!asAttr) + return 0; // default AS + if (auto targetAddrSpaceAttr = + mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(asAttr)) + return targetAddrSpaceAttr.getValue(); + + if (mlir::isa_and_present<cir::LangAddressSpaceAttr>(asAttr)) + llvm_unreachable("lowering LangAddressSpaceAttr NYI"); + + llvm_unreachable("unexpected address Space attribute kindI"); +} static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, mlir::DataLayout &dataLayout, cir::LowerModule *lowerModule) { converter.addConversion([&](cir::PointerType type) -> mlir::Type { - unsigned addrSpace = - type.getAddrSpace() ? type.getAddrSpace().getValue().getUInt() : 0; - return mlir::LLVM::LLVMPointerType::get(type.getContext(), addrSpace); + mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr = type.getAddrSpace(); + unsigned numericAS = getNumericASFromCIRAS(addrSpaceAttr, lowerModule); + return mlir::LLVM::LLVMPointerType::get(type.getContext(), numericAS); }); converter.addConversion([&](cir::VPtrType type) -> mlir::Type { assert(!cir::MissingFeatures::addressSpace()); diff --git a/clang/test/CIR/IR/address-space.cir b/clang/test/CIR/IR/address-space.cir new file mode 100644 index 0000000000000..9a729c934bc11 --- /dev/null +++ b/clang/test/CIR/IR/address-space.cir @@ -0,0 +1,41 @@ +// RUN: cir-opt %s --verify-roundtrip | FileCheck %s + +!s32i = !cir.int<s, 32> + +module { + cir.func @target_address_space_ptr(%p: !cir.ptr<!s32i, target_address_space(1)>) { + cir.return + } + + cir.func @lang_address_space_offload_local(%p: !cir.ptr<!s32i, lang_address_space(offload_local)>) { + cir.return + } + + cir.func @lang_address_space_offload_global(%p: !cir.ptr<!s32i, lang_address_space(offload_global)>) { + cir.return + } + + cir.func @lang_address_space_offload_constant(%p: !cir.ptr<!s32i, lang_address_space(offload_constant)>) { + cir.return + } + + cir.func @lang_address_space_offload_private(%p: !cir.ptr<!s32i, lang_address_space(offload_private)>) { + cir.return + } + + cir.func @lang_address_space_offload_generic(%p: !cir.ptr<!s32i, lang_address_space(offload_generic)>) { + cir.return + } + + cir.func @default_address_space(%p: !cir.ptr<!s32i>) { + cir.return + } +} + +// CHECK: cir.func @target_address_space_ptr(%arg0: !cir.ptr<!s32i, target_address_space(1)>) +// CHECK: cir.func @lang_address_space_offload_local(%arg0: !cir.ptr<!s32i, lang_address_space(offload_local)>) +// CHECK: cir.func @lang_address_space_offload_global(%arg0: !cir.ptr<!s32i, lang_address_space(offload_global)>) +// CHECK: cir.func @lang_address_space_offload_constant(%arg0: !cir.ptr<!s32i, lang_address_space(offload_constant)>) +// CHECK: cir.func @lang_address_space_offload_private(%arg0: !cir.ptr<!s32i, lang_address_space(offload_private)>) +// CHECK: cir.func @lang_address_space_offload_generic(%arg0: !cir.ptr<!s32i, lang_address_space(offload_generic)>) +// CHECK: cir.func @default_address_space(%arg0: !cir.ptr<!s32i>) diff --git a/clang/test/CIR/IR/invalid-addrspace.cir b/clang/test/CIR/IR/invalid-addrspace.cir index 4b6a388b1e4a8..d38868f1febf0 100644 --- a/clang/test/CIR/IR/invalid-addrspace.cir +++ b/clang/test/CIR/IR/invalid-addrspace.cir @@ -3,7 +3,7 @@ // ----- !u64i = !cir.int<u, 64> -// expected-error @below {{expected 'target_address_space'}} +// expected-error @+1 {{unknown address space specifier 'foobar'; expected 'target_address_space' or 'lang_address_space'}} cir.func @address_space1(%p : !cir.ptr<!u64i, foobar>) { cir.return } @@ -11,6 +11,7 @@ cir.func @address_space1(%p : !cir.ptr<!u64i, foobar>) { // ----- !u64i = !cir.int<u, 64> +// expected-error@below {{expected '(' after 'target_address_space'}} // expected-error@below {{expected '('}} cir.func @address_space2(%p : !cir.ptr<!u64i, target_address_space>) { cir.return @@ -19,8 +20,33 @@ cir.func @address_space2(%p : !cir.ptr<!u64i, target_address_space>) { // ----- !u64i = !cir.int<u, 64> -// expected-error@+2 {{expected integer value}} -// expected-error@below {{expected integer address space value}} +// expected-error@below {{expected target address space value}} +// expected-error@below {{expected integer value}} cir.func @address_space3(%p : !cir.ptr<!u64i, target_address_space()>) { cir.return } + +// ----- + +!u64i = !cir.int<u, 64> +// expected-error@below {{expected '(' after 'lang_address_space'}} +// expected-error@below {{expected '('}} +cir.func @lang_address_space_no_parens(%p : !cir.ptr<!u64i, lang_address_space>) { + cir.return +} + +// ----- + +!u64i = !cir.int<u, 64> +// expected-error@+1 {{expected keyword for language address space kind}} +cir.func @lang_address_space_empty(%p : !cir.ptr<!u64i, lang_address_space()>) { + cir.return +} + +// ----- + +!u64i = !cir.int<u, 64> +// expected-error@+1 {{expected one of [default, offload_private, offload_local, offload_global, offload_constant, offload_generic] for language address space kind}} +cir.func @lang_address_space_invalid(%p : !cir.ptr<!u64i, lang_address_space(foobar)>) { + cir.return +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
