[clang] 3896212 - [CIR] Implement Target-specific address space handling support for `PointerType` (#161028)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 3 18:40:59 PDT 2025
Author: David Rivera
Date: 2025-10-03T21:40:54-04:00
New Revision: 3896212ceab8fe963335e8a31b898b6099292c88
URL: https://github.com/llvm/llvm-project/commit/3896212ceab8fe963335e8a31b898b6099292c88
DIFF: https://github.com/llvm/llvm-project/commit/3896212ceab8fe963335e8a31b898b6099292c88.diff
LOG: [CIR] Implement Target-specific address space handling support for `PointerType` (#161028)
This PR adds support for address spaces in CIR pointer types by:
1. Introducing a `TargetAddressSpaceAttr` to represent target-specific
numeric address spaces (A Lang-specific attribute is to be implemented
in a different PR)
2. Extending the `PointerType` to include an optional address space
parameter
3. Adding helper methods in `CIRBaseBuilder` to create pointers with
address spaces
4. Implementing custom parsers and printers for address space attributes
5. Updating the LLVM lowering to properly handle address spaces when
converting CIR to LLVM IR
The implementation allows for creating pointers with specific address
spaces, which is necessary for supporting language features like Clang's
`__attribute__((address_space(N)))`. Address spaces are preserved
through the CIR representation and correctly lowered to LLVM IR.
Added:
clang/test/CIR/CodeGen/address-space.c
clang/test/CIR/IR/invalid-addrspace.cir
Modified:
clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
clang/include/clang/CIR/Dialect/IR/CIRTypes.h
clang/include/clang/CIR/Dialect/IR/CIRTypes.td
clang/include/clang/CIR/MissingFeatures.h
clang/lib/CIR/CodeGen/CIRGenExpr.cpp
clang/lib/CIR/CodeGen/CIRGenModule.cpp
clang/lib/CIR/CodeGen/CIRGenTypeCache.h
clang/lib/CIR/CodeGen/CIRGenTypes.cpp
clang/lib/CIR/CodeGen/TargetInfo.h
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
clang/lib/CIR/Dialect/IR/CIRTypes.cpp
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 8a5bf0376ec98..93d81e37c9240 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H
#include "clang/AST/CharUnits.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/CIRTypes.h"
@@ -129,8 +130,30 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::PointerType::get(ty);
}
- cir::PointerType getVoidPtrTy() {
- return getPointerTo(cir::VoidType::get(getContext()));
+ cir::PointerType getPointerTo(mlir::Type ty, cir::TargetAddressSpaceAttr as) {
+ return cir::PointerType::get(ty, as);
+ }
+
+ cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
+ if (langAS == clang::LangAS::Default) // Default address space.
+ 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");
+ }
+
+ cir::PointerType getVoidPtrTy(clang::LangAS langAS = clang::LangAS::Default) {
+ return getPointerTo(cir::VoidType::get(getContext()), langAS);
+ }
+
+ cir::PointerType getVoidPtrTy(cir::TargetAddressSpaceAttr as) {
+ return getPointerTo(cir::VoidType::get(getContext()), as);
}
cir::BoolAttr getCIRBoolAttr(bool state) {
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
index 925a9a87e267f..03a6a97dc8c2e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
@@ -15,6 +15,7 @@
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributeInterfaces.h"
+#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index f8358de9a1eb9..7714750a53d44 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -601,6 +601,33 @@ def CIR_VTableAttr : CIR_Attr<"VTable", "vtable", [TypedAttrInterface]> {
}];
}
+//===----------------------------------------------------------------------===//
+// TargetAddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace",
+ "target_address_space"> {
+ let summary = "Represents a target-specific numeric address space";
+ let description = [{
+ The TargetAddressSpaceAttr represents a target-specific numeric address space,
+ corresponding to the LLVM IR `addressspace` qualifier and the clang
+ `address_space` attribute.
+
+ A value of zero represents the default address space. The semantics of non-zero
+ address spaces are target-specific.
+
+ Example:
+ ```mlir
+ // Target-specific numeric address spaces
+ !cir.ptr<!s32i, addrspace(target<1>)>
+ !cir.ptr<!s32i, addrspace(target<10>)>
+ ```
+ }];
+
+ let parameters = (ins "mlir::IntegerAttr":$value);
+ let assemblyFormat = "`<` `target` `<` $value `>` `>`";
+}
+
//===----------------------------------------------------------------------===//
// ConstComplexAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
index bfa165cdd945e..45f646f1c9dfa 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
@@ -16,6 +16,9 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Interfaces/CIRTypeInterfaces.h"
namespace cir {
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 4eec34cb299ab..313184764f536 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -14,10 +14,12 @@
#define CLANG_CIR_DIALECT_IR_CIRTYPES_TD
include "clang/CIR/Dialect/IR/CIRDialect.td"
+include "clang/CIR/Dialect/IR/CIREnumAttr.td"
include "clang/CIR/Dialect/IR/CIRTypeConstraints.td"
include "clang/CIR/Interfaces/CIRTypeInterfaces.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/EnumAttr.td"
//===----------------------------------------------------------------------===//
// CIR Types
@@ -226,32 +228,54 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
]> {
let summary = "CIR pointer type";
let description = [{
- The `!cir.ptr` type represents C and C++ pointer types and C++ reference
- types, other than pointers-to-members. The `pointee` type is the type
- pointed to.
+ The `!cir.ptr` type is a typed pointer type. It is used to represent
+ pointers to objects in C/C++. The type of the pointed-to object is given by
+ the `pointee` parameter. The `addrSpace` parameter is an optional address
+ space attribute that specifies the address space of the pointer. If not
+ specified, the pointer is assumed to be in the default address space.
- TODO(CIR): The address space attribute is not yet implemented.
+ The `!cir.ptr` type can point to any type, including fundamental types,
+ records, arrays, vectors, functions, and other pointers. It can also point
+ to incomplete types, such as incomplete records.
+
+ Examples:
+
+ ```mlir
+ !cir.ptr<!cir.int<u, 8>>
+ !cir.ptr<!cir.float>
+ !cir.ptr<!cir.record<struct "MyStruct">>
+ !cir.ptr<!cir.int<u, 8>, target_address_space(1)>
+ !cir.ptr<!cir.record<struct "MyStruct">, target_address_space(5)>
+ ```
}];
- let parameters = (ins "mlir::Type":$pointee);
+ let parameters = (ins
+ "mlir::Type":$pointee,
+ OptionalParameter<
+ "cir::TargetAddressSpaceAttr">:$addrSpace
+ );
+ let skipDefaultBuilders = 1;
let builders = [
- TypeBuilderWithInferredContext<(ins "mlir::Type":$pointee), [{
- return $_get(pointee.getContext(), pointee);
+ TypeBuilderWithInferredContext<(ins
+ "mlir::Type":$pointee,
+ CArg<"cir::TargetAddressSpaceAttr", "nullptr">:$addrSpace), [{
+ return $_get(pointee.getContext(), pointee, addrSpace);
}]>,
- TypeBuilder<(ins "mlir::Type":$pointee), [{
- return $_get($_ctxt, pointee);
+ TypeBuilder<(ins
+ "mlir::Type":$pointee,
+ CArg<"cir::TargetAddressSpaceAttr", "nullptr">:$addrSpace), [{
+ return $_get($_ctxt, pointee, addrSpace);
}]>
];
let assemblyFormat = [{
- `<` $pointee `>`
+ `<`
+ $pointee
+ ( `,` ` ` custom<TargetAddressSpace>($addrSpace)^ )?
+ `>`
}];
- let genVerifyDecl = 1;
-
- let skipDefaultBuilders = 1;
-
let extraClassDeclaration = [{
template <typename ...Types>
bool isPtrTo() const {
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 0e7cec4e1a0e0..f7ca2761b85c5 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -216,6 +216,7 @@ struct MissingFeatures {
static bool dataLayoutTypeIsSized() { return false; }
static bool dataLayoutTypeAllocSize() { return false; }
static bool dataLayoutTypeStoreSize() { return false; }
+ static bool dataLayoutPtrHandlingBasedOnLangAS() { return false; }
static bool deferredCXXGlobalInit() { return false; }
static bool deleteArray() { return false; }
static bool devirtualizeMemberFunction() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index b4c8924d14b73..be948908e18d5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2053,8 +2053,8 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
// CIR uses its own alloca address space rather than follow the target data
// layout like original CodeGen. The data layout awareness should be done in
// the lowering pass instead.
- assert(!cir::MissingFeatures::addressSpace());
- cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
+ cir::PointerType localVarPtrTy =
+ builder.getPointerTo(ty, getCIRAllocaAddressSpace());
mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
mlir::Value addr;
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 8485564a4a117..910c8a9b8f98a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -76,6 +76,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true);
UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false);
UInt8PtrTy = cir::PointerType::get(UInt8Ty);
+ cirAllocaAddressSpace = getTargetCIRGenInfo().getCIRAllocaAddressSpace();
UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false);
UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false);
UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false);
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
index cc3ce09be4f95..273ec7f06b4b5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
+++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H
#include "clang/AST/CharUnits.h"
+#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
namespace clang::CIRGen {
@@ -73,6 +74,8 @@ struct CIRGenTypeCache {
/// The alignment of size_t.
unsigned char SizeAlignInBytes;
+ cir::TargetAddressSpaceAttr cirAllocaAddressSpace;
+
clang::CharUnits getSizeAlign() const {
return clang::CharUnits::fromQuantity(SizeAlignInBytes);
}
@@ -80,6 +83,10 @@ struct CIRGenTypeCache {
clang::CharUnits getPointerAlign() const {
return clang::CharUnits::fromQuantity(PointerAlignInBytes);
}
+
+ cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const {
+ return cirAllocaAddressSpace;
+ }
};
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index bb24933a22ed7..e65896a9ff109 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -417,7 +417,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
mlir::Type pointeeType = convertType(elemTy);
- resultType = builder.getPointerTo(pointeeType);
+ resultType = builder.getPointerTo(pointeeType, elemTy.getAddressSpace());
break;
}
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h
index a5c548aa2c7c4..dbb0312c76040 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 "clang/Basic/AddressSpaces.h"
#include <memory>
#include <utility>
@@ -43,6 +44,11 @@ class TargetCIRGenInfo {
/// Returns ABI info helper for the target.
const ABIInfo &getABIInfo() const { return *info; }
+ /// Get the address space for alloca.
+ virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const {
+ return {};
+ }
+
/// Determine whether a call to an unprototyped functions under
/// the given calling convention should use the variadic
/// convention or the non-variadic convention.
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 95faad6746955..3484c59df4ece 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -43,6 +43,16 @@ parseFloatLiteral(mlir::AsmParser &parser,
mlir::FailureOr<llvm::APFloat> &value,
cir::FPTypeInterface fpType);
+//===----------------------------------------------------------------------===//
+// AddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
+ cir::TargetAddressSpaceAttr &attr);
+
+void printTargetAddressSpace(mlir::AsmPrinter &p,
+ cir::TargetAddressSpaceAttr attr);
+
static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
mlir::IntegerAttr &value);
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 35b4513c5789f..5897352829891 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -13,6 +13,7 @@
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "mlir/IR/DialectImplementation.h"
+#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIRTypesDetails.h"
#include "clang/CIR/MissingFeatures.h"
@@ -38,6 +39,27 @@ parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
static void printFuncTypeParams(mlir::AsmPrinter &p,
mlir::ArrayRef<mlir::Type> params,
bool isVarArg);
+//===----------------------------------------------------------------------===//
+// CIR Custom Parser/Printer Signatures
+//===----------------------------------------------------------------------===//
+
+static mlir::ParseResult
+parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
+ bool &isVarArg);
+
+static void printFuncTypeParams(mlir::AsmPrinter &p,
+ mlir::ArrayRef<mlir::Type> params,
+ bool isVarArg);
+
+//===----------------------------------------------------------------------===//
+// AddressSpace
+//===----------------------------------------------------------------------===//
+
+mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
+ cir::TargetAddressSpaceAttr &attr);
+
+void printTargetAddressSpace(mlir::AsmPrinter &p,
+ cir::TargetAddressSpaceAttr attr);
//===----------------------------------------------------------------------===//
// Get autogenerated stuff
@@ -297,6 +319,22 @@ bool RecordType::isLayoutIdentical(const RecordType &other) {
// Data Layout information for types
//===----------------------------------------------------------------------===//
+llvm::TypeSize
+PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
+ ::mlir::DataLayoutEntryListRef params) const {
+ // FIXME: improve this in face of address spaces
+ assert(!cir::MissingFeatures::dataLayoutPtrHandlingBasedOnLangAS());
+ return llvm::TypeSize::getFixed(64);
+}
+
+uint64_t
+PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
+ ::mlir::DataLayoutEntryListRef params) const {
+ // FIXME: improve this in face of address spaces
+ assert(!cir::MissingFeatures::dataLayoutPtrHandlingBasedOnLangAS());
+ return 8;
+}
+
llvm::TypeSize
RecordType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
@@ -766,30 +804,39 @@ mlir::LogicalResult cir::VectorType::verify(
}
//===----------------------------------------------------------------------===//
-// PointerType Definitions
+// TargetAddressSpace definitions
//===----------------------------------------------------------------------===//
-llvm::TypeSize
-PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout,
- ::mlir::DataLayoutEntryListRef params) const {
- // FIXME: improve this in face of address spaces
- return llvm::TypeSize::getFixed(64);
-}
+mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
+ cir::TargetAddressSpaceAttr &attr) {
+ if (failed(p.parseKeyword("target_address_space")))
+ return mlir::failure();
-uint64_t
-PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
- ::mlir::DataLayoutEntryListRef params) const {
- // FIXME: improve this in face of address spaces
- return 8;
-}
+ if (failed(p.parseLParen()))
+ return mlir::failure();
-mlir::LogicalResult
-PointerType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
- mlir::Type pointee) {
- // TODO(CIR): Verification of the address space goes here.
+ int32_t targetValue;
+ if (failed(p.parseInteger(targetValue)))
+ return p.emitError(p.getCurrentLocation(),
+ "expected integer address space value");
+
+ if (failed(p.parseRParen()))
+ return p.emitError(p.getCurrentLocation(),
+ "expected ')' after address space value");
+
+ mlir::MLIRContext *context = p.getBuilder().getContext();
+ attr = cir::TargetAddressSpaceAttr::get(
+ context, p.getBuilder().getUI32IntegerAttr(targetValue));
return mlir::success();
}
+// 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() << ")";
+}
+
//===----------------------------------------------------------------------===//
// CIR Dialect
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4bc7783175120..bfb1262dec1f3 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -32,6 +32,7 @@
#include "mlir/Transforms/DialectConversion.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"
@@ -2308,11 +2309,9 @@ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite(
static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
mlir::DataLayout &dataLayout) {
converter.addConversion([&](cir::PointerType type) -> mlir::Type {
- // Drop pointee type since LLVM dialect only allows opaque pointers.
- assert(!cir::MissingFeatures::addressSpace());
- unsigned targetAS = 0;
-
- return mlir::LLVM::LLVMPointerType::get(type.getContext(), targetAS);
+ unsigned addrSpace =
+ type.getAddrSpace() ? type.getAddrSpace().getValue().getUInt() : 0;
+ return mlir::LLVM::LLVMPointerType::get(type.getContext(), addrSpace);
});
converter.addConversion([&](cir::VPtrType type) -> mlir::Type {
assert(!cir::MissingFeatures::addressSpace());
diff --git a/clang/test/CIR/CodeGen/address-space.c b/clang/test/CIR/CodeGen/address-space.c
new file mode 100644
index 0000000000000..a334b8a2907e4
--- /dev/null
+++ b/clang/test/CIR/CodeGen/address-space.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// Test address space 1
+// CIR: cir.func dso_local @foo(%arg0: !cir.ptr<!s32i, target_address_space(1)>
+// LLVM: define dso_local void @foo(ptr addrspace(1) %0)
+// OGCG: define dso_local void @foo(ptr addrspace(1) noundef %arg)
+void foo(int __attribute__((address_space(1))) *arg) {
+ return;
+}
+
+// Test explicit address space 0 (should be same as default)
+// CIR: cir.func dso_local @bar(%arg0: !cir.ptr<!s32i, target_address_space(0)>
+// LLVM: define dso_local void @bar(ptr %0)
+// OGCG: define dso_local void @bar(ptr noundef %arg)
+void bar(int __attribute__((address_space(0))) *arg) {
+ return;
+}
+
+// Test default address space (no attribute)
+// CIR: cir.func dso_local @baz(%arg0: !cir.ptr<!s32i>
+// LLVM: define dso_local void @baz(ptr %0)
+// OGCG: define dso_local void @baz(ptr noundef %arg)
+void baz(int *arg) {
+ return;
+}
diff --git a/clang/test/CIR/IR/invalid-addrspace.cir b/clang/test/CIR/IR/invalid-addrspace.cir
new file mode 100644
index 0000000000000..8f188b840bdec
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-addrspace.cir
@@ -0,0 +1,27 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+// -----
+
+!u64i = !cir.int<u, 64>
+// expected-error @below {{expected 'target_address_space'}}
+cir.func @address_space1(%p : !cir.ptr<!u64i, foobar>) {
+ cir.return
+}
+
+// -----
+
+!u64i = !cir.int<u, 64>
+// expected-error at below {{expected '('}}
+cir.func @address_space2(%p : !cir.ptr<!u64i, target_address_space>) {
+ cir.return
+}
+
+// -----
+
+!u64i = !cir.int<u, 64>
+// expected-error at +2 {{expected integer value}}
+// expected-error at below {{expected integer address space value}}
+cir.func @address_space3(%p : !cir.ptr<!u64i, target_address_space()>) {
+ cir.return
+}
+
More information about the cfe-commits
mailing list