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
**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}
```
10 lines
439 B
MLIR
10 lines
439 B
MLIR
// RUN: mlir-opt %s --verify-roundtrip
|
|
|
|
// Check that LLVM ops accept ptr values.
|
|
llvm.func @llvm_ops_with_ptr_values(%arg0: !llvm.ptr, %arg1: !llvm.struct<(!ptr.ptr<#llvm.address_space<3>>)>) {
|
|
%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.store %arg1, %arg0 : !llvm.struct<(!ptr.ptr<#llvm.address_space<3>>)>, !llvm.ptr
|
|
llvm.return
|
|
}
|