[Mlir-commits] [mlir] [mlir][LLVM|ptr] Add the `#llvm.address_space` attribute, and allow `ptr` translation (PR #156333)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Sep 1 07:43:20 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-mlir-llvm
Author: Fabian Mora (fabianmcg)
<details>
<summary>Changes</summary>
This commit introduces the `#llvm.address_space` attribute. This attribute implements the `ptr::MemorySpaceAttrInterface`, establishing the semantics of the LLVM address space.
This allows making `!ptr.ptr` translatable to LLVM IR as long it uses the `#llvm.address_space` attribute.
Concretely, `!ptr.ptr<#llvm.address_space<N>>` now translates to `ptr addrspace(N)`.
Additionally, this patch makes `PtrLikeTypes` with no metadata, no element type, and with `#llvm.address_space` memory space, compatible with the LLVM dialect.
**Infrastructure Updates:**
- Refactor `ptr::MemorySpaceAttrInterface` to include DataLayout parameter for better validation
- Add new utility functions `LLVM::isLoadableType()` and `LLVM::isTypeCompatibleWithAtomicOp()`
- Update type compatibility checks to support ptr-like types with LLVM address spaces
- Splice the `MemorySpaceAttrInterface` to its own library, so the LLVMDialect won't depend on the PtrDialect yet
- It also updates some ptr enums with new cases.
**Translation Support:**
- New `PtrToLLVMIRTranslation` module for converting ptr dialect to LLVM IR
- Type translation support for ptr types with LLVM address spaces
- Proper address space preservation during IR lowering
Example:
```mlir
llvm.func @<!-- -->llvm_ops_with_ptr_values(%arg0: !llvm.ptr) {
%1 = llvm.load %arg0 : !llvm.ptr -> !ptr.ptr<#llvm.address_space<1>>
llvm.store %1, %arg0 : !ptr.ptr<#llvm.address_space<1>>, !llvm.ptr
llvm.return
}
```
Translates to:
```llvmir
; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"
define void @<!-- -->llvm_ops_with_ptr_values(ptr %0) {
%2 = load ptr addrspace(1), ptr %0, align 8
store ptr addrspace(1) %2, ptr %0, align 8
ret void
}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
```
---
Patch is 38.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/156333.diff
30 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+36)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h (+1)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h (+10)
- (modified) mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt (-2)
- (modified) mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h (+4-2)
- (modified) mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td (+4)
- (modified) mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h (+1-2)
- (added) mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.h (+21)
- (modified) mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td (+6-1)
- (modified) mlir/include/mlir/Target/LLVMIR/Dialect/All.h (+2)
- (added) mlir/include/mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h (+31)
- (modified) mlir/lib/Dialect/LLVMIR/CMakeLists.txt (+1)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp (+84)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+2-2)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp (+3-1)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp (+29-2)
- (modified) mlir/lib/Dialect/Ptr/IR/CMakeLists.txt (+20)
- (added) mlir/lib/Dialect/Ptr/IR/MemorySpaceInterfaces.cpp (+15)
- (modified) mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp (+4)
- (modified) mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp (+4-6)
- (modified) mlir/lib/Target/LLVMIR/CMakeLists.txt (+1)
- (modified) mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt (+1)
- (added) mlir/lib/Target/LLVMIR/Dialect/Ptr/CMakeLists.txt (+12)
- (added) mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp (+60)
- (modified) mlir/lib/Target/LLVMIR/TypeToLLVM.cpp (+10-1)
- (added) mlir/test/Dialect/LLVMIR/ptr.mlir (+9)
- (modified) mlir/test/Dialect/Ptr/invalid.mlir (+16)
- (modified) mlir/test/Dialect/Ptr/ops.mlir (+14)
- (added) mlir/test/Target/LLVMIR/ptr.mlir (+16)
- (modified) mlir/test/lib/Dialect/Test/TestAttributes.cpp (+4)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
index bfce904a18d4f..32670a78a40f9 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
@@ -11,6 +11,7 @@
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
+include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/CommonAttrConstraints.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
@@ -23,6 +24,41 @@ class LLVM_Attr<string name, string attrMnemonic,
let mnemonic = attrMnemonic;
}
+//===----------------------------------------------------------------------===//
+// AddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_AddressSpaceAttr :
+ LLVM_Attr<"AddressSpace", "address_space", [
+ DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
+ ]> {
+ let summary = "LLVM address space";
+ let description = [{
+ The `address_space` attribute represents an LLVM address space. It takes an
+ unsigned integer parameter that specifies the address space number.
+
+ Different address spaces in LLVM can have different properties:
+ - Address space 0 is the default/generic address space
+ - Other address spaces may have specific semantics (e.g., shared memory,
+ constant memory, etc.) depending on the target architecture
+
+ Example:
+
+ ```mlir
+ // Address space 0 (default)
+ #llvm.address_space<0>
+
+ // Address space 1 (e.g., global memory on some targets)
+ #llvm.address_space<1>
+
+ // Address space 3 (e.g., shared memory on some GPU targets)
+ #llvm.address_space<3>
+ ```
+ }];
+ let parameters = (ins "unsigned":$addressSpace);
+ let assemblyFormat = "`<` $addressSpace `>`";
+}
+
//===----------------------------------------------------------------------===//
// CConvAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
index 1ceeb7e4ba2a5..fafccf304e1b4 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
@@ -15,6 +15,7 @@
#define MLIR_DIALECT_LLVMIR_LLVMATTRS_H_
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
#include <optional>
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
index 17561f79d135a..a1506497dc85c 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
@@ -28,6 +28,7 @@ namespace mlir {
class AsmParser;
class AsmPrinter;
+class DataLayout;
namespace LLVM {
class LLVMDialect;
@@ -111,6 +112,15 @@ bool isCompatibleFloatingPointType(Type type);
/// dialect pointers and LLVM dialect scalable vector types.
bool isCompatibleVectorType(Type type);
+/// Returns `true` if the given type is a loadable type compatible with the LLVM
+/// dialect.
+bool isLoadableType(Type type);
+
+/// Returns true if the given type is supported by atomic operations. All
+/// integer, float, and pointer types with a power-of-two bitsize and a minimal
+/// size of 8 bits are supported.
+bool isTypeCompatibleWithAtomicOp(Type type, const DataLayout &dataLayout);
+
/// Returns the element count of any LLVM-compatible vector type.
llvm::ElementCount getVectorNumElements(Type type);
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
index fa4914b179b7a..388d735843c4e 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
@@ -7,8 +7,6 @@ mlir_tablegen(PtrOpsAttrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=ptr)
add_mlir_dialect_tablegen_target(MLIRPtrOpsAttributesIncGen)
set(LLVM_TARGET_DEFINITIONS MemorySpaceInterfaces.td)
-mlir_tablegen(MemorySpaceInterfaces.h.inc -gen-op-interface-decls)
-mlir_tablegen(MemorySpaceInterfaces.cpp.inc -gen-op-interface-defs)
mlir_tablegen(MemorySpaceAttrInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(MemorySpaceAttrInterfaces.cpp.inc -gen-attr-interface-defs)
add_mlir_dialect_tablegen_target(MLIRPtrMemorySpaceInterfacesIncGen)
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h
index 3e6754c6bec99..4d65c8d807cb9 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h
@@ -17,8 +17,12 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/OpDefinition.h"
+#include <functional>
+#include <optional>
+
namespace mlir {
class Operation;
+class DataLayout;
namespace ptr {
enum class AtomicBinOp : uint32_t;
enum class AtomicOrdering : uint32_t;
@@ -27,6 +31,4 @@ enum class AtomicOrdering : uint32_t;
#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc"
-#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc"
-
#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
index 0171b9ca2e5dc..27d94621cc85c 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
@@ -43,6 +43,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
/*args=*/ (ins "::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
+ "std::optional<std::reference_wrapper<const ::mlir::DataLayout>>":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
@@ -58,6 +59,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
/*args=*/ (ins "::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
+ "std::optional<std::reference_wrapper<const ::mlir::DataLayout>>":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
@@ -74,6 +76,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
"::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
+ "std::optional<std::reference_wrapper<const ::mlir::DataLayout>>":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
@@ -91,6 +94,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
"::mlir::ptr::AtomicOrdering":$successOrdering,
"::mlir::ptr::AtomicOrdering":$failureOrdering,
"std::optional<int64_t>":$alignment,
+ "std::optional<std::reference_wrapper<const ::mlir::DataLayout>>":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
index dc0a3ffd4ae33..bb01ceaaeea54 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
@@ -19,10 +19,9 @@
#include "llvm/Support/TypeSize.h"
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
+#include "mlir/Dialect/Ptr/IR/PtrEnums.h"
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.h.inc"
-#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc"
-
#endif // MLIR_DIALECT_PTR_IR_PTRATTRS_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.h
new file mode 100644
index 0000000000000..2e98df8654b71
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.h
@@ -0,0 +1,21 @@
+//===- PtrEnums.h - `ptr` dialect enums -------------------------*- C++ -*-===//
+//
+// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the `ptr` dialect enums.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_PTR_IR_PTRENUMS_H
+#define MLIR_DIALECT_PTR_IR_PTRENUMS_H
+
+#include "mlir/IR/BuiltinAttributeInterfaces.h"
+#include "mlir/IR/OpImplementation.h"
+
+#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc"
+
+#endif // MLIR_DIALECT_PTR_IR_PTRENUMS_H
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index c169f48e573d0..5f5e3d9dd7e17 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -32,6 +32,10 @@ def AtomicBinOpFMax : I32EnumCase<"fmax", 13, "fmax">;
def AtomicBinOpFMin : I32EnumCase<"fmin", 14, "fmin">;
def AtomicBinOpUIncWrap : I32EnumCase<"uinc_wrap", 15, "uinc_wrap">;
def AtomicBinOpUDecWrap : I32EnumCase<"udec_wrap", 16, "udec_wrap">;
+def AtomicBinOpUSubCond : I32EnumCase<"usub_cond", 17, "usub_cond">;
+def AtomicBinOpUSubSat : I32EnumCase<"usub_sat", 18, "usub_sat">;
+def AtomicBinOpFMaximum : I32EnumCase<"fmaximum", 19, "fmaximum">;
+def AtomicBinOpFMinimum : I32EnumCase<"fminimum", 20, "fminimum">;
def AtomicBinOp : I32Enum<
"AtomicBinOp",
@@ -40,7 +44,8 @@ def AtomicBinOp : I32Enum<
AtomicBinOpNand, AtomicBinOpOr, AtomicBinOpXor, AtomicBinOpMax,
AtomicBinOpMin, AtomicBinOpUMax, AtomicBinOpUMin, AtomicBinOpFAdd,
AtomicBinOpFSub, AtomicBinOpFMax, AtomicBinOpFMin, AtomicBinOpUIncWrap,
- AtomicBinOpUDecWrap]> {
+ AtomicBinOpUDecWrap, AtomicBinOpUSubCond, AtomicBinOpUSubSat,
+ AtomicBinOpFMaximum, AtomicBinOpFMinimum]> {
let cppNamespace = "::mlir::ptr";
}
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
index e4670cb1a9622..05b66ace902ad 100644
--- a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h
@@ -25,6 +25,7 @@
#include "mlir/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
@@ -45,6 +46,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry ®istry) {
registerNVVMDialectTranslation(registry);
registerOpenACCDialectTranslation(registry);
registerOpenMPDialectTranslation(registry);
+ registerPtrDialectTranslation(registry);
registerROCDLDialectTranslation(registry);
registerSPIRVDialectTranslation(registry);
registerVCIXDialectTranslation(registry);
diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h b/mlir/include/mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h
new file mode 100644
index 0000000000000..5c81762ba1a8a
--- /dev/null
+++ b/mlir/include/mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h
@@ -0,0 +1,31 @@
+//===- PtrToLLVMIRTranslation.h - `ptr` to LLVM IR --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides registration calls for `ptr` dialect to LLVM IR translation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H
+#define MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H
+
+namespace mlir {
+
+class DialectRegistry;
+class MLIRContext;
+
+/// Register the `ptr` dialect and the translation from it to the LLVM IR in the
+/// given registry;
+void registerPtrDialectTranslation(DialectRegistry ®istry);
+
+/// Register the `ptr` dialect and the translation from it in the registry
+/// associated with the given context.
+void registerPtrDialectTranslation(MLIRContext &context);
+
+} // namespace mlir
+
+#endif // MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H
diff --git a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
index ff55f17315cfd..ec581ac7277e3 100644
--- a/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Dialect/LLVMIR/CMakeLists.txt
@@ -32,6 +32,7 @@ add_mlir_dialect_library(MLIRLLVMDialect
MLIRInferTypeOpInterface
MLIRIR
MLIRMemorySlotInterfaces
+ MLIRPtrMemorySpaceInterfaces
MLIRSideEffectInterfaces
MLIRSupport
)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
index 9d7a23f028cb0..822e6408ad6de 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
@@ -12,6 +12,8 @@
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
+#include "mlir/Dialect/Ptr/IR/PtrEnums.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
@@ -50,6 +52,88 @@ void LLVMDialect::registerAttributes() {
>();
}
+//===----------------------------------------------------------------------===//
+// AddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+/// Checks whether the given type is an LLVM type that can be loaded or stored.
+static bool isValidLoadStoreImpl(
+ Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
+ std::optional<std::reference_wrapper<const ::mlir::DataLayout>> dataLayout,
+ function_ref<InFlightDiagnostic()> emitError) {
+ if (!isLoadableType(type)) {
+ if (emitError)
+ emitError() << "type must be LLVM type with size, but got " << type;
+ return false;
+ }
+ if (ordering == ptr::AtomicOrdering::not_atomic)
+ return true;
+
+ // To check atomic validity we need a datalayout.
+ if (!dataLayout.has_value()) {
+ if (emitError)
+ emitError() << "expected a valid data layout";
+ return false;
+ }
+ if (!isTypeCompatibleWithAtomicOp(type, dataLayout->get())) {
+ if (emitError)
+ emitError() << "unsupported type " << type << " for atomic access";
+ return false;
+ }
+ return true;
+}
+
+bool AddressSpaceAttr::isValidLoad(
+ Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
+ std::optional<std::reference_wrapper<const ::mlir::DataLayout>> dataLayout,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
+}
+
+bool AddressSpaceAttr::isValidStore(
+ Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
+ std::optional<std::reference_wrapper<const ::mlir::DataLayout>> dataLayout,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
+}
+
+bool AddressSpaceAttr::isValidAtomicOp(
+ ptr::AtomicBinOp op, Type type, ptr::AtomicOrdering ordering,
+ std::optional<int64_t> alignment,
+ std::optional<std::reference_wrapper<const ::mlir::DataLayout>> dataLayout,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once `ptr.atomic_rmw` is implemented.
+ assert(false && "unimplemented, see TODO in the source.");
+ return false;
+}
+
+bool AddressSpaceAttr::isValidAtomicXchg(
+ Type type, ptr::AtomicOrdering successOrdering,
+ ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment,
+ std::optional<std::reference_wrapper<const ::mlir::DataLayout>> dataLayout,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once `ptr.atomic_cmpxchg` is implemented.
+ assert(false && "unimplemented, see TODO in the source.");
+ return false;
+}
+
+bool AddressSpaceAttr::isValidAddrSpaceCast(
+ Type tgt, Type src, function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once the `ptr.addrspace_cast` op is added to the
+ // dialect.
+ assert(false && "unimplemented, see TODO in the source.");
+ return false;
+}
+
+bool AddressSpaceAttr::isValidPtrIntCast(
+ Type intLikeTy, Type ptrLikeTy,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once the int-cast ops are added to the `ptr`
+ // dialect.
+ assert(false && "unimplemented, see TODO in the source.");
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// AliasScopeAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index a0b755bc63736..ef2707089a45c 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -853,8 +853,8 @@ void LoadOp::getEffects(
/// Returns true if the given type is supported by atomic operations. All
/// integer, float, and pointer types with a power-of-two bitsize and a minimal
/// size of 8 bits are supported.
-static bool isTypeCompatibleWithAtomicOp(Type type,
- const DataLayout &dataLayout) {
+bool LLVM::isTypeCompatibleWithAtomicOp(Type type,
+ const DataLayout &dataLayout) {
if (!isa<IntegerType, LLVMPointerType>(type))
if (!isCompatibleFloatingPointType(type))
return false;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp
index 78b44116bb4fa..297640cdd49d0 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp
@@ -24,7 +24,9 @@ using namespace mlir::LLVM;
/// prints it as usual.
static void dispatchPrint(AsmPrinter &printer, Type type) {
if (isCompatibleType(type) &&
- !llvm::isa<IntegerType, FloatType, VectorType>(type))
+ !(llvm::isa<IntegerType, FloatType, VectorType>(type) ||
+ (llvm::isa<PtrLikeTypeInterface>(type) &&
+ !llvm::isa<LLVMPointerType>(type))))
return mlir::LLVM::detail::printType(type, printer);
printer.printType(type);
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index fee2d3ed62930..2dd0132a65bc4 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -13,6 +13,7 @@
#include "TypeDetail.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/BuiltinTypes.h"
@@ -701,6 +702,17 @@ const llvm::fltSemantics &LLVMPPCFP128Type::getFloatSemantics() const {
// Utility functions.
//===----------------------------------------------------------------------===//
+/// Check whether type is a compatible ptr type. These are pointer-like types
+/// with no element type, no metadata, and using the LLVM AddressSpaceAttr
+/// memory space.
+static bool isCompatiblePtrType(Type type) {
+ auto ptrTy = dyn_cast<PtrLikeTypeInterface>(type);
+ if (!ptrTy)
+ return false;
+ return !ptrTy.hasPtrMetadata() && ptrTy.getElementType(...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/156333
More information about the Mlir-commits
mailing list