https://github.com/RiverDave updated 
https://github.com/llvm/llvm-project/pull/179054

>From 2b9aff28821fc4ad6901916d76128c7cec333444 Mon Sep 17 00:00:00 2001
From: David Rivera <[email protected]>
Date: Sat, 31 Jan 2026 12:05:56 -0500
Subject: [PATCH] [CIR] Infrastructure for Language-specific Address Spaces

---
 clang/include/clang/CIR/Dialect/IR/CIRAttrs.h |   1 +
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |  53 ++++++++-
 .../clang/CIR/Dialect/IR/CIREnumAttr.td       |  19 +++
 clang/include/clang/CIR/Dialect/IR/CIRTypes.h |   4 +
 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp         | 108 ++++++++++++++++-
 clang/lib/CIR/Dialect/IR/CIRTypes.cpp         | 112 +++++++++++++++++-
 6 files changed, 290 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
index 858d4d6350bed..1d61bd998c216 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
@@ -13,6 +13,7 @@
 #ifndef CLANG_CIR_DIALECT_IR_CIRATTRS_H
 #define CLANG_CIR_DIALECT_IR_CIRATTRS_H
 
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
 #include "mlir/IR/Attributes.h"
 #include "mlir/IR/BuiltinAttributeInterfaces.h"
 #include "clang/Basic/AddressSpaces.h"
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 2309811815f27..4fbab2e83663d 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -14,6 +14,7 @@
 #define CLANG_CIR_DIALECT_IR_CIRATTRS_TD
 
 include "mlir/IR/BuiltinAttributeInterfaces.td"
+include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
 
 include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
 include "clang/CIR/Dialect/IR/CIRDialect.td"
@@ -766,16 +767,64 @@ def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", 
"dyn_cast_info"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// LangAddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_LangAddressSpaceAttr : CIR_EnumAttr<CIR_LangAddressSpace,
+                                            "lang_address_space", [
+    DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
+]> {
+  let summary = "Represents a language address space";
+  let description = [{
+    Encodes the semantic address spaces defined by the front-end language
+    (e.g. `__shared__`, `__constant__`, `__local__`). Values are stored using 
the
+    `cir::LangAddressSpace` enum, keeping the representation compact and
+    preserving the qualifier until it is mapped onto target/LLVM address-space
+    numbers.
+
+    Example:
+    ```mlir
+    !cir.ptr<!s32i, lang_address_space(offload_local)>
+    cir.global constant external lang_address_space(offload_constant)
+    ```
+  }];
+
+  let builders = [
+    AttrBuilder<(ins "clang::LangAS":$langAS), [{
+      return $_get($_ctxt, cir::toCIRLangAddressSpace(langAS));
+    }]>
+  ];
+
+  let assemblyFormat = [{
+    `(` custom<AddressSpaceValue>($value) `)`
+  }];
+
+  let defaultValue = "cir::LangAddressSpace::Default";
+
+  let extraClassDeclaration = [{
+    unsigned getAsUnsignedValue() const;
+  }];
+
+  let extraClassDefinition = [{
+    unsigned $cppClass::getAsUnsignedValue() const {
+      return static_cast<unsigned>(getValue());
+    }
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // TargetAddressSpaceAttr
 
//===----------------------------------------------------------------------===//
 
 def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace",
-                                         "target_address_space"> {
+                                         "target_address_space", [
+    DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
+  ]> {
   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
+    corresponding to the LLVM IR `addrspace` qualifier and the clang
      `address_space` attribute.
     
     A value of zero represents the default address space. The semantics of 
non-zero
diff --git a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td 
b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
index 98b8a31d2a18a..1de6ffdc08d72 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
@@ -14,6 +14,7 @@
 #define CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
 
 include "mlir/IR/EnumAttr.td"
+include "clang/CIR/Dialect/IR/CIRDialect.td"
 
 class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
     : I32EnumAttr<name, summary, cases> {
@@ -35,4 +36,22 @@ class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, 
string value = "">
   let defaultValue = value;
 }
 
+def CIR_LangAddressSpace : CIR_I32EnumAttr<
+  "LangAddressSpace", "language address space kind", [
+  I32EnumAttrCase<"Default", 0, "default">,
+  I32EnumAttrCase<"OffloadPrivate", 1, "offload_private">,
+  I32EnumAttrCase<"OffloadLocal", 2, "offload_local">,
+  I32EnumAttrCase<"OffloadGlobal", 3, "offload_global">,
+  I32EnumAttrCase<"OffloadConstant", 4, "offload_constant">,
+  I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic">
+]> {
+  let description = [{
+    Enumerates language-specific address spaces used by CIR. These represent
+    semantic qualifiers from source languages (e.g., CUDA `__shared__`,
+    OpenCL `__local`) before target lowering.
+  }];
+
+  let genSpecializedAttr = 0;
+}
+
 #endif // CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
index 939e774a6ea67..16c48ba4fb4e9 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
@@ -13,6 +13,7 @@
 #ifndef CLANG_CIR_DIALECT_IR_CIRTYPES_H
 #define CLANG_CIR_DIALECT_IR_CIRTYPES_H
 
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
 #include "mlir/IR/Attributes.h"
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/MLIRContext.h"
@@ -43,6 +44,9 @@ bool isSized(mlir::Type ty);
 
//===----------------------------------------------------------------------===//
 // AddressSpace helpers
 
//===----------------------------------------------------------------------===//
+
+cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS);
+
 cir::TargetAddressSpaceAttr toCIRTargetAddressSpace(mlir::MLIRContext &context,
                                                     clang::LangAS langAS);
 
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 2f4240c385cab..f528f54511a57 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -10,6 +10,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 
 #include "mlir/IR/DialectImplementation.h"
@@ -47,11 +48,21 @@ parseFloatLiteral(mlir::AsmParser &parser,
 // AddressSpaceAttr
 
//===----------------------------------------------------------------------===//
 
-mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
-                                          cir::TargetAddressSpaceAttr &attr);
+mlir::ParseResult parseAddressSpaceValue(mlir::AsmParser &p,
+                                         cir::LangAddressSpace &addrSpace) {
+  llvm::SMLoc loc = p.getCurrentLocation();
+  mlir::FailureOr<cir::LangAddressSpace> result =
+      mlir::FieldParser<cir::LangAddressSpace>::parse(p);
+  if (mlir::failed(result))
+    return p.emitError(loc, "expected address space keyword");
+  addrSpace = result.value();
+  return mlir::success();
+}
 
-void printTargetAddressSpace(mlir::AsmPrinter &p,
-                             cir::TargetAddressSpaceAttr attr);
+void printAddressSpaceValue(mlir::AsmPrinter &p,
+                            cir::LangAddressSpace addrSpace) {
+  p << cir::stringifyEnum(addrSpace);
+}
 
 static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
                                        mlir::IntegerAttr &value);
@@ -64,6 +75,95 @@ static void printConstPtr(mlir::AsmPrinter &p, 
mlir::IntegerAttr value);
 using namespace mlir;
 using namespace cir;
 
+//===----------------------------------------------------------------------===//
+// MemorySpaceAttrInterface implementations for Lang and Target address space
+// attributes
+//===----------------------------------------------------------------------===//
+
+bool LangAddressSpaceAttr::isValidLoad(
+    mlir::Type type, mlir::ptr::AtomicOrdering ordering,
+    std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidLoad for LangAddressSpaceAttr NYI");
+}
+
+bool LangAddressSpaceAttr::isValidStore(
+    mlir::Type type, mlir::ptr::AtomicOrdering ordering,
+    std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidStore for LangAddressSpaceAttr NYI");
+}
+
+bool LangAddressSpaceAttr::isValidAtomicOp(
+    mlir::ptr::AtomicBinOp op, mlir::Type type,
+    mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
+    const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAtomicOp for LangAddressSpaceAttr NYI");
+}
+
+bool LangAddressSpaceAttr::isValidAtomicXchg(
+    mlir::Type type, mlir::ptr::AtomicOrdering successOrdering,
+    mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> 
alignment,
+    const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAtomicXchg for LangAddressSpaceAttr NYI");
+}
+
+bool LangAddressSpaceAttr::isValidAddrSpaceCast(
+    mlir::Type tgt, mlir::Type src,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAddrSpaceCast for LangAddressSpaceAttr NYI");
+}
+
+bool LangAddressSpaceAttr::isValidPtrIntCast(
+    mlir::Type intLikeTy, mlir::Type ptrLikeTy,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidPtrIntCast for LangAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidLoad(
+    mlir::Type type, mlir::ptr::AtomicOrdering ordering,
+    std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidLoad for TargetAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidStore(
+    mlir::Type type, mlir::ptr::AtomicOrdering ordering,
+    std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidStore for TargetAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidAtomicOp(
+    mlir::ptr::AtomicBinOp op, mlir::Type type,
+    mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
+    const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAtomicOp for TargetAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidAtomicXchg(
+    mlir::Type type, mlir::ptr::AtomicOrdering successOrdering,
+    mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> 
alignment,
+    const mlir::DataLayout *dataLayout,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAtomicXchg for TargetAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidAddrSpaceCast(
+    mlir::Type tgt, mlir::Type src,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidAddrSpaceCast for TargetAddressSpaceAttr NYI");
+}
+
+bool TargetAddressSpaceAttr::isValidPtrIntCast(
+    mlir::Type intLikeTy, mlir::Type ptrLikeTy,
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const {
+  llvm_unreachable("isValidPtrIntCast for TargetAddressSpaceAttr NYI");
+}
+
 
//===----------------------------------------------------------------------===//
 // General CIR parsing / printing
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp 
b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 43853b6696a94..8d97a8d5c88cd 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -60,6 +60,14 @@ static void printFuncTypeParams(mlir::AsmPrinter &p,
 // AddressSpace
 
//===----------------------------------------------------------------------===//
 
+mlir::ParseResult
+parseAddressSpaceValue(mlir::AsmParser &p,
+                       mlir::ptr::MemorySpaceAttrInterface &attr);
+
+void printAddressSpaceValue(mlir::AsmPrinter &printer,
+                            mlir::ptr::MemorySpaceAttrInterface attr);
+
+// Custom parser/printer for the `addrSpace` parameter in `!cir.ptr`.
 mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
                                           cir::TargetAddressSpaceAttr &attr);
 
@@ -930,9 +938,111 @@ void cir::VectorType::print(mlir::AsmPrinter &odsPrinter) 
const {
 }
 
 
//===----------------------------------------------------------------------===//
-// TargetAddressSpace definitions
+// AddressSpace definitions
 
//===----------------------------------------------------------------------===//
 
+cir::LangAddressSpace cir::toCIRLangAddressSpace(clang::LangAS langAS) {
+  using clang::LangAS;
+  switch (langAS) {
+  case LangAS::Default:
+    return LangAddressSpace::Default;
+  case LangAS::opencl_global:
+    return LangAddressSpace::OffloadGlobal;
+  case LangAS::opencl_local:
+  case LangAS::cuda_shared:
+    // Local means local among the work-group (OpenCL) or block (CUDA).
+    // All threads inside the kernel can access local memory.
+    return LangAddressSpace::OffloadLocal;
+  case LangAS::cuda_device:
+    return LangAddressSpace::OffloadGlobal;
+  case LangAS::opencl_constant:
+  case LangAS::cuda_constant:
+    return LangAddressSpace::OffloadConstant;
+  case LangAS::opencl_private:
+    return LangAddressSpace::OffloadPrivate;
+  case LangAS::opencl_generic:
+    return LangAddressSpace::OffloadGeneric;
+  case LangAS::opencl_global_device:
+  case LangAS::opencl_global_host:
+  case LangAS::sycl_global:
+  case LangAS::sycl_global_device:
+  case LangAS::sycl_global_host:
+  case LangAS::sycl_local:
+  case LangAS::sycl_private:
+  case LangAS::ptr32_sptr:
+  case LangAS::ptr32_uptr:
+  case LangAS::ptr64:
+  case LangAS::hlsl_groupshared:
+  case LangAS::wasm_funcref:
+    llvm_unreachable("NYI");
+  default:
+    llvm_unreachable("unknown/unsupported clang language address space");
+  }
+}
+
+mlir::ParseResult
+parseAddressSpaceValue(mlir::AsmParser &p,
+                       mlir::ptr::MemorySpaceAttrInterface &attr) {
+
+  llvm::SMLoc loc = p.getCurrentLocation();
+
+  // Try to parse target address space first.
+  attr = nullptr;
+  if (p.parseOptionalKeyword("target_address_space").succeeded()) {
+    unsigned val;
+    if (p.parseLParen())
+      return p.emitError(loc, "expected '(' after 'target_address_space'");
+
+    if (p.parseInteger(val))
+      return p.emitError(loc, "expected target address space value");
+
+    if (p.parseRParen())
+      return p.emitError(loc, "expected ')'");
+
+    attr = cir::TargetAddressSpaceAttr::get(
+        p.getContext(), p.getBuilder().getUI32IntegerAttr(val));
+    return mlir::success();
+  }
+
+  // Try to parse language specific address space.
+  if (p.parseOptionalKeyword("lang_address_space").succeeded()) {
+    if (p.parseLParen())
+      return p.emitError(loc, "expected '(' after 'lang_address_space'");
+
+    mlir::FailureOr<cir::LangAddressSpace> result =
+        mlir::FieldParser<cir::LangAddressSpace>::parse(p);
+    if (mlir::failed(result))
+      return p.emitError(loc, "expected language address space keyword");
+
+    if (p.parseRParen())
+      return p.emitError(loc, "expected ')'");
+
+    attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
+    return mlir::success();
+  }
+
+  return mlir::success();
+}
+
+void printAddressSpaceValue(mlir::AsmPrinter &p,
+                            mlir::ptr::MemorySpaceAttrInterface attr) {
+  if (!attr)
+    return;
+
+  if (auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) {
+    p << "lang_address_space("
+      << cir::stringifyLangAddressSpace(language.getValue()) << ')';
+    return;
+  }
+
+  if (auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) {
+    p << "target_address_space(" << target.getValue() << ')';
+    return;
+  }
+
+  llvm_unreachable("unexpected address-space attribute kind");
+}
+
 cir::TargetAddressSpaceAttr
 cir::toCIRTargetAddressSpace(mlir::MLIRContext &context, clang::LangAS langAS) 
{
   return cir::TargetAddressSpaceAttr::get(

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

Reply via email to