[Mlir-commits] [mlir] [mlir][LLVM] Add support for `ptrtoaddr` (PR #185104)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Mar 6 12:48:08 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm
Author: Markus Böck (zero9178)
<details>
<summary>Changes</summary>
The `ptrtoaddr` op is akin to `ptrtoint` with some important differences:
* It does not capture the provenance of the pointer, meaning a pointer does not escape and subsequent `inttoptr` don't make a legal pointer. LLVM can then assume the pointer never escaped, which helps alias analysis.
* It does not support arbitrary integer types, but only exactly the integer type that is equal in width to the pointer type as specified by the data layout.
This PR adds the op the MLIR dialect and adds the corresponding verification for the datalayout property.
---
Full diff: https://github.com/llvm/llvm-project/pull/185104.diff
6 Files Affected:
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+8)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+15)
- (modified) mlir/test/Dialect/LLVMIR/invalid.mlir (+18)
- (modified) mlir/test/Dialect/LLVMIR/roundtrip.mlir (+2)
- (modified) mlir/test/Target/LLVMIR/Import/instructions.ll (+2)
- (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+9)
``````````diff
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 0957f751bf44b..1a4e79899c923 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -629,6 +629,14 @@ def LLVM_IntToPtrOp : LLVM_DereferenceableCastOp<"inttoptr", "IntToPtr",
def LLVM_PtrToIntOp : LLVM_CastOp<"ptrtoint", "PtrToInt",
LLVM_ScalarOrVectorOf<LLVM_AnyPointer>,
LLVM_ScalarOrVectorOf<AnySignlessInteger>>;
+
+def LLVM_PtrToAddrOp : LLVM_CastOp<"ptrtoaddr", "PtrToAddr",
+ LLVM_ScalarOrVectorOf<LLVM_AnyPointer>,
+ LLVM_ScalarOrVectorOf<AnySignlessInteger>> {
+ let llvmBuilder = "$res = builder.CreatePtrToAddr($arg);";
+ let hasVerifier = 1;
+}
+
def LLVM_SExtOp : LLVM_CastOp<"sext", "SExt",
LLVM_ScalarOrVectorOf<AnySignlessInteger>,
LLVM_ScalarOrVectorOf<AnySignlessInteger>> {
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index d960201e2b3d0..38ad55db916ef 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -3854,6 +3854,21 @@ LogicalResult LLVM::BitcastOp::verify() {
return success();
}
+LogicalResult LLVM::PtrToAddrOp::verify() {
+ auto pointerType =
+ cast<LLVM::LLVMPointerType>(extractVectorElementType(getArg().getType()));
+ auto integerType = cast<IntegerType>(extractVectorElementType(getType()));
+
+ auto dataLayout = DataLayout::closest(*this);
+ unsigned width = dataLayout.getTypeSizeInBits(pointerType);
+ if (width != integerType.getWidth())
+ return emitOpError("bit-width of integer result type ")
+ << integerType << " must match the pointer bitwidth (" << width
+ << ") specified in the datalayout";
+
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// Folder for LLVM::AddrSpaceCastOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 5068ddc42e1e5..7f3eb20ce00fa 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -2072,3 +2072,21 @@ module {
// expected-error at +1 {{'llvm.blockaddress' op expects an existing block label target in the referenced function}}
%0 = llvm.blockaddress <function = @missing_func, tag = <id = 1>> : !llvm.ptr
}
+
+// -----
+
+llvm.func @too_narrow_ptr_to_addr(%arg0 : !llvm.ptr) -> () {
+ // expected-error at +1 {{'llvm.ptrtoaddr' op bit-width of integer result type 'i32' must match the pointer bitwidth (64) specified in the datalayout}}
+ %0 = llvm.ptrtoaddr %arg0 : !llvm.ptr to i32
+}
+
+// -----
+
+module attributes { dlti.dl_spec = #dlti.dl_spec<
+ #dlti.dl_entry<!llvm.ptr, dense<[32, 32, 64]> : vector<3xi64>>
+>} {
+ llvm.func @too_narrow_ptr_to_addr(%arg0 : !llvm.ptr) -> () {
+ // expected-error at +1 {{'llvm.ptrtoaddr' op bit-width of integer result type 'i64' must match the pointer bitwidth (32) specified in the datalayout}}
+ %0 = llvm.ptrtoaddr %arg0 : !llvm.ptr to i64
+ }
+}
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index c680d0d98ac5f..1b3e0750a9aab 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -243,8 +243,10 @@ func.func @ops(%arg0: i32, %arg1: f32,
//
// CHECK: %[[PTR:.*]] = llvm.inttoptr %[[I32]] : i32 to !llvm.ptr
// CHECK: %{{.*}} = llvm.ptrtoint %[[PTR]] : !llvm.ptr to i32
+// CHECK: %{{.*}} = llvm.ptrtoaddr %[[PTR]] : !llvm.ptr to i64
%25 = llvm.inttoptr %arg0 : i32 to !llvm.ptr
%26 = llvm.ptrtoint %25 : !llvm.ptr to i32
+ %a26 = llvm.ptrtoaddr %25 : !llvm.ptr to i64
// Extended and Quad floating point
//
diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll
index 22a274049ecf4..a67ab1c9e9c56 100644
--- a/mlir/test/Target/LLVMIR/Import/instructions.ll
+++ b/mlir/test/Target/LLVMIR/Import/instructions.ll
@@ -184,10 +184,12 @@ define void @integer_extension_and_truncation(i32 %arg1) {
define ptr @pointer_casts(ptr %arg1, i64 %arg2) {
; CHECK: %[[NULL:[0-9]+]] = llvm.mlir.zero : !llvm.ptr
; CHECK: llvm.ptrtoint %[[ARG1]] : !llvm.ptr to i64
+ ; CHECK: llvm.ptrtoaddr %[[ARG1]] : !llvm.ptr to i64
; CHECK: llvm.inttoptr %[[ARG2]] : i64 to !llvm.ptr
; CHECK: llvm.bitcast %[[ARG1]] : !llvm.ptr to !llvm.ptr
; CHECK: llvm.return %[[NULL]] : !llvm.ptr
%1 = ptrtoint ptr %arg1 to i64
+ %p = ptrtoaddr ptr %arg1 to i64
%2 = inttoptr i64 %arg2 to ptr
%3 = bitcast ptr %arg1 to ptr
ret ptr null
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 4fb5285584a89..a0d32e270caaa 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1283,6 +1283,15 @@ llvm.func @intpointerconversion(%arg0 : i32) -> i32 {
llvm.return %2 : i32
}
+// CHECK-LABEL: @addrpointerconversion
+// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]
+llvm.func @addrpointerconversion(%arg0 : !llvm.ptr) -> i64 {
+ // CHECK: %[[PTR:.*]] = ptrtoaddr ptr %[[ARG0]] to i64
+ // CHECK-NEXT: ret i64 %[[PTR]]
+ %1 = llvm.ptrtoaddr %arg0 : !llvm.ptr to i64
+ llvm.return %1 : i64
+}
+
llvm.func @fpconversion(%arg0 : i32) -> i32 {
// CHECK: %2 = sitofp i32 %0 to float
// CHECK-NEXT: %3 = fptosi float %2 to i32
``````````
</details>
https://github.com/llvm/llvm-project/pull/185104
More information about the Mlir-commits
mailing list