Author: David Rivera
Date: 2026-02-27T23:08:20-05:00
New Revision: 0b88ee12dd88cb27275750406364fad014d87d65

URL: 
https://github.com/llvm/llvm-project/commit/0b88ee12dd88cb27275750406364fad014d87d65
DIFF: 
https://github.com/llvm/llvm-project/commit/0b88ee12dd88cb27275750406364fad014d87d65.diff

LOG: [CIR] Infrastructure and MemorySpaceAttrInterface for Address Spaces 
(#179073)

Related: https://github.com/llvm/llvm-project/issues/175871,
https://github.com/issues/assigned?issue=llvm%7Cllvm-project%7C179278,
https://github.com/issues/assigned?issue=llvm%7Cllvm-project%7C160386

- Introducing the LangAddressSpace enum with offload address space kinds
(offload_private, offload_local, offload_global, offload_constant,
offload_generic) and the LangAddressSpaceAttr attribute.


- Generalizes CIR AS attributes as MemorySpaceAttrInterface and Attaches
it to `PointerType`. Includes test coverage for valid IR roundtrips and
invalid address space parsing.

This starts a series of patches with the purpose of bringing complete
address spaces support features for CIR. Most of the test coverage is
provided in subsequent patches further down the stack. note that most of
these patches are based on: https://github.com/llvm/clangir/pull/1986

Added: 
    clang/test/CIR/IR/address-space.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/CIREnumAttr.td
    clang/include/clang/CIR/Dialect/IR/CIRTypes.h
    clang/include/clang/CIR/Dialect/IR/CIRTypes.td
    clang/lib/CIR/CodeGen/Address.h
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
    clang/lib/CIR/CodeGen/CIRGenExpr.cpp
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
    clang/lib/CIR/CodeGen/CIRGenTypeCache.h
    clang/lib/CIR/CodeGen/TargetInfo.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
    clang/test/CIR/IR/invalid-addrspace.cir

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index efae3d9d894ed..32d0921d15363 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -155,29 +155,25 @@ 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) {
     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.h 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
index eb87dc083b0f5..f6674a10af66b 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 845ec4a85fa7d..b1be1d5daf4e0 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"
@@ -783,16 +784,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
@@ -806,7 +855,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/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..9988a6fdd4b8f 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,12 +44,25 @@ bool isSized(mlir::Type ty);
 
//===----------------------------------------------------------------------===//
 // AddressSpace helpers
 
//===----------------------------------------------------------------------===//
-cir::TargetAddressSpaceAttr toCIRTargetAddressSpace(mlir::MLIRContext &context,
-                                                    clang::LangAS langAS);
 
-bool isMatchingAddressSpace(cir::TargetAddressSpaceAttr cirAS,
+cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS);
+
+// Compare a CIR memory space attribute with a Clang LangAS.
+bool isMatchingAddressSpace(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);
+
+/// Normalize LangAddressSpace::Default to null (empty attribute).
+mlir::ptr::MemorySpaceAttrInterface
+normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace);
+
+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 ea2113432d5b5..450c02135e033 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -252,19 +252,23 @@ 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), [{
+        // Drop default address space and replace with empty attribute.
+        addrSpace = cir::normalizeDefaultAddressSpace(addrSpace);
         return $_get(pointee.getContext(), pointee, addrSpace);
     }]>,
     TypeBuilder<(ins
       "mlir::Type":$pointee,
-      CArg<"cir::TargetAddressSpaceAttr", "nullptr">:$addrSpace), [{
+      CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace), [{
+        // Drop default address space and replace with empty attribute.
+        addrSpace = cir::normalizeDefaultAddressSpace(addrSpace);
         return $_get($_ctxt, pointee, addrSpace);
     }]>
   ];
@@ -272,7 +276,7 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
   let assemblyFormat = [{
     `<`
       $pointee
-      ( `,` ` ` custom<TargetAddressSpace>($addrSpace)^ )?
+      ( `,` ` ` custom<AddressSpaceValue>($addrSpace)^ )?
     `>`
   }];
 
@@ -303,6 +307,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 a27e66e0989fa..86d34be0a311c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -381,7 +381,7 @@ static RValue emitBuiltinAlloca(CIRGenFunction &cgf, const 
CallExpr *e,
           cgf.getCIRAllocaAddressSpace(),
           e->getType()->getPointeeType().getAddressSpace())) {
     cgf.cgm.errorNYI(e->getSourceRange(),
-                     "Non-default address space for alloca");
+                     "Address Space Cast for builtin alloca");
   }
 
   // Bitcast the alloca to the expected type.
@@ -825,7 +825,7 @@ decodeFixedType(CIRGenFunction &cgf,
   case IITDescriptor::Pointer: {
     mlir::Builder builder(context);
     auto addrSpace = cir::TargetAddressSpaceAttr::get(
-        context, builder.getUI32IntegerAttr(descriptor.Pointer_AddressSpace));
+        context, descriptor.Pointer_AddressSpace);
     return cir::PointerType::get(cir::VoidType::get(context), addrSpace);
   }
   default:

diff  --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 89d887b2a682d..4eccf430cd622 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"
@@ -1455,9 +1456,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(),

diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index ea9029775c228..03c8369753f35 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"
 

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 5a0c854db9125..2f3824d3d47a7 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"
 

diff  --git a/clang/lib/CIR/CodeGen/TargetInfo.h 
b/clang/lib/CIR/CodeGen/TargetInfo.h
index 79325c2d35c4d..f4792d5309e36 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.h
+++ b/clang/lib/CIR/CodeGen/TargetInfo.h
@@ -16,8 +16,10 @@
 
 #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"
+#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
 
 #include <memory>
 #include <utility>
@@ -48,8 +50,9 @@ class TargetCIRGenInfo {
   const ABIInfo &getABIInfo() const { return *info; }
 
   /// Get the address space for alloca.
-  virtual cir::TargetAddressSpaceAttr getCIRAllocaAddressSpace() const {
-    return {};
+  virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const 
{
+    return cir::LangAddressSpaceAttr::get(&info->cgt.getMLIRContext(),
+                                          cir::LangAddressSpace::Default);
   }
 
   /// Determine whether a call to an unprototyped functions under

diff  --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 43bd33759fba9..67509f3cf452a 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..80dce3d3266b5 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"
@@ -60,6 +63,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,58 +941,171 @@ void cir::VectorType::print(mlir::AsmPrinter 
&odsPrinter) const {
 }
 
 
//===----------------------------------------------------------------------===//
-// TargetAddressSpace definitions
+// AddressSpace definitions
 
//===----------------------------------------------------------------------===//
 
-cir::TargetAddressSpaceAttr
-cir::toCIRTargetAddressSpace(mlir::MLIRContext &context, clang::LangAS langAS) 
{
-  return cir::TargetAddressSpaceAttr::get(
-      &context,
-      IntegerAttr::get(&context,
-                       llvm::APSInt(clang::toTargetAddressSpace(langAS))));
+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) {
+  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");
+  }
 }
 
-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;
+mlir::ParseResult
+parseAddressSpaceValue(mlir::AsmParser &p,
+                       mlir::ptr::MemorySpaceAttrInterface &attr) {
 
-  if (!isTargetAddressSpace(as))
-    return false;
+  llvm::SMLoc loc = p.getCurrentLocation();
 
-  return cirAS.getValue().getUInt() == toTargetAddressSpace(as);
-}
+  // 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'");
 
-mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p,
-                                          cir::TargetAddressSpaceAttr &attr) {
-  if (failed(p.parseKeyword("target_address_space")))
-    return mlir::failure();
+    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(), val);
+    return mlir::success();
+  }
 
-  if (failed(p.parseLParen()))
-    return mlir::failure();
+  // 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'");
 
-  int32_t targetValue;
-  if (failed(p.parseInteger(targetValue)))
-    return p.emitError(p.getCurrentLocation(),
-                       "expected integer address space value");
+    mlir::FailureOr<cir::LangAddressSpace> result =
+        mlir::FieldParser<cir::LangAddressSpace>::parse(p);
+    if (mlir::failed(result))
+      return mlir::failure();
 
-  if (failed(p.parseRParen()))
-    return p.emitError(p.getCurrentLocation(),
-                       "expected ')' after address space value");
+    if (p.parseRParen())
+      return p.emitError(loc, "expected ')'");
+
+    attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value());
+    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'";
 
-  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() << ")";
+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");
+}
+
+mlir::ptr::MemorySpaceAttrInterface cir::normalizeDefaultAddressSpace(
+    mlir::ptr::MemorySpaceAttrInterface addrSpace) {
+  if (auto langAS =
+          mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpace))
+    if (langAS.getValue() == cir::LangAddressSpace::Default)
+      return {};
+  return addrSpace;
+}
+
+mlir::ptr::MemorySpaceAttrInterface
+cir::toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS) {
+  using clang::LangAS;
+
+  if (langAS == LangAS::Default)
+    return cir::LangAddressSpaceAttr::get(&ctx, 
cir::LangAddressSpace::Default);
+
+  if (clang::isTargetAddressSpace(langAS)) {
+    unsigned targetAS = clang::toTargetAddressSpace(langAS);
+    return cir::TargetAddressSpaceAttr::get(&ctx, targetAS);
+  }
+
+  return cir::LangAddressSpaceAttr::get(&ctx, toCIRLangAddressSpace(langAS));
+}
+
+bool cir::isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS,
+                                 clang::LangAS as) {
+  cirAS = normalizeDefaultAddressSpace(cirAS);
+  if (!cirAS)
+    return as == clang::LangAS::Default;
+  mlir::ptr::MemorySpaceAttrInterface expected = normalizeDefaultAddressSpace(
+      toCIRAddressSpaceAttr(*cirAS.getContext(), as));
+  return expected == cirAS;
+}
+
+//===----------------------------------------------------------------------===//
+// PointerType Definitions
+//===----------------------------------------------------------------------===//
+
+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'";
+    }
+  }
+
+  return success();
 }
 
 
//===----------------------------------------------------------------------===//

diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 3318638b8a03d..03085ad29ab78 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/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
@@ -41,6 +43,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"
 
@@ -3254,9 +3257,17 @@ mlir::LogicalResult 
CIRToLLVMSelectOpLowering::matchAndRewrite(
 static void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
                                  mlir::DataLayout &dataLayout) {
   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 = 0;
+
+    if (auto langAsAttr =
+            
mlir::dyn_cast_if_present<cir::LangAddressSpaceAttr>(addrSpaceAttr))
+      llvm_unreachable("lowering LangAddressSpaceAttr NYI");
+    else if (auto targetAsAttr =
+                 mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>(
+                     addrSpaceAttr))
+      numericAS = targetAsAttr.getValue();
+    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
+}


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

Reply via email to