[llvm] [llubi] Implement ptrtoaddr (PR #203771)
Zhige Chen via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 14 07:30:32 PDT 2026
https://github.com/nofe1248 created https://github.com/llvm/llvm-project/pull/203771
This PR implements the `ptrtoaddr` instruction.
>From ef5a76f56578e18121f0330be7f7a8c39e063d21 Mon Sep 17 00:00:00 2001
From: Zhige Chen <zhigec_cpp at outlook.com>
Date: Sun, 14 Jun 2026 22:29:33 +0800
Subject: [PATCH] [llubi] Implement ptrtoaddr instruction
---
llvm/test/tools/llubi/ptrtoaddr.ll | 25 +++++++++++++++++++
.../tools/llubi/ptrtoaddr_after_ptrtoint.ll | 21 ++++++++++++++++
llvm/test/tools/llubi/ptrtoaddr_no_expose.ll | 20 +++++++++++++++
llvm/tools/llubi/lib/Interpreter.cpp | 11 ++++++--
4 files changed, 75 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/tools/llubi/ptrtoaddr.ll
create mode 100644 llvm/test/tools/llubi/ptrtoaddr_after_ptrtoint.ll
create mode 100644 llvm/test/tools/llubi/ptrtoaddr_no_expose.ll
diff --git a/llvm/test/tools/llubi/ptrtoaddr.ll b/llvm/test/tools/llubi/ptrtoaddr.ll
new file mode 100644
index 0000000000000..6def7c3b2fa0e
--- /dev/null
+++ b/llvm/test/tools/llubi/ptrtoaddr.ll
@@ -0,0 +1,25 @@
+; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-p:64:64:64-p1:64:64:64:32"
+
+define void @main() {
+ %wide1 = inttoptr i64 4294967301 to ptr addrspace(1)
+ %repr1 = ptrtoint ptr addrspace(1) %wide1 to i64
+ %addr1 = ptrtoaddr ptr addrspace(1) %wide1 to i32
+
+ %wide2 = inttoptr <2 x i64> <i64 4294967301, i64 4294967303> to <2 x ptr addrspace(1)>
+ %repr2 = ptrtoint <2 x ptr addrspace(1)> %wide2 to <2 x i64>
+ %addr2 = ptrtoaddr <2 x ptr addrspace(1)> %wide2 to <2 x i32>
+
+ ret void
+}
+
+; CHECK: Entering function: main
+; CHECK-NEXT: %wide1 = inttoptr i64 4294967301 to ptr addrspace(1) => ptr 0x100000005 [nullary]
+; CHECK-NEXT: %repr1 = ptrtoint ptr addrspace(1) %wide1 to i64 => i64 4294967301
+; CHECK-NEXT: %addr1 = ptrtoaddr ptr addrspace(1) %wide1 to i32 => i32 5
+; CHECK-NEXT: %wide2 = inttoptr <2 x i64> <i64 4294967301, i64 4294967303> to <2 x ptr addrspace(1)> => { ptr 0x100000005 [nullary], ptr 0x100000007 [nullary] }
+; CHECK-NEXT: %repr2 = ptrtoint <2 x ptr addrspace(1)> %wide2 to <2 x i64> => { i64 4294967301, i64 4294967303 }
+; CHECK-NEXT: %addr2 = ptrtoaddr <2 x ptr addrspace(1)> %wide2 to <2 x i32> => { i32 5, i32 7 }
+; CHECK-NEXT: ret void
+; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/ptrtoaddr_after_ptrtoint.ll b/llvm/test/tools/llubi/ptrtoaddr_after_ptrtoint.ll
new file mode 100644
index 0000000000000..5cbf4818b8b56
--- /dev/null
+++ b/llvm/test/tools/llubi/ptrtoaddr_after_ptrtoint.ll
@@ -0,0 +1,21 @@
+; RUN: llubi --verbose < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-p:64:64:64"
+
+define void @main() {
+ %p = alloca i32
+ %i = ptrtoint ptr %p to i64
+ %a = ptrtoaddr ptr %p to i64
+ %p2 = inttoptr i64 %a to ptr
+ store i32 0, ptr %p2
+ ret void
+}
+
+; CHECK: Entering function: main
+; CHECK-NEXT: %p = alloca i32, align 4 => ptr 0x8 [p]
+; CHECK-NEXT: %i = ptrtoint ptr %p to i64 => i64 8
+; CHECK-NEXT: %a = ptrtoaddr ptr %p to i64 => i64 8
+; CHECK-NEXT: %p2 = inttoptr i64 %a to ptr => ptr 0x8 [wildcard]
+; CHECK-NEXT: store i32 0, ptr %p2, align 4
+; CHECK-NEXT: ret void
+; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/ptrtoaddr_no_expose.ll b/llvm/test/tools/llubi/ptrtoaddr_no_expose.ll
new file mode 100644
index 0000000000000..ccd75aeb77042
--- /dev/null
+++ b/llvm/test/tools/llubi/ptrtoaddr_no_expose.ll
@@ -0,0 +1,20 @@
+; RUN: not llubi --verbose < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-p:64:64:64"
+
+define void @main() {
+ %alloc = alloca i32
+ %addr = ptrtoaddr ptr %alloc to i64
+ %cast = inttoptr i64 %addr to ptr
+ store i32 0, ptr %cast
+ ret void
+}
+
+; CHECK: Entering function: main
+; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
+; CHECK-NEXT: %addr = ptrtoaddr ptr %alloc to i64 => i64 8
+; CHECK-NEXT: %cast = inttoptr i64 %addr to ptr => ptr 0x8 [nullary]
+; CHECK-NEXT: Stacktrace:
+; CHECK-NEXT: #0 store i32 0, ptr %cast, align 4 at @main {{.*}}
+; CHECK-NEXT: Immediate UB detected: Invalid memory access via a pointer with nullary provenance.
+; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/tools/llubi/lib/Interpreter.cpp b/llvm/tools/llubi/lib/Interpreter.cpp
index 5769d0a4a9c4d..5f7c48794245d 100644
--- a/llvm/tools/llubi/lib/Interpreter.cpp
+++ b/llvm/tools/llubi/lib/Interpreter.cpp
@@ -2246,8 +2246,6 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
});
}
- // TODO: Add support for ptrtoaddr, which exposes nothing.
-
void visitIntToPtr(IntToPtrInst &I) {
return visitUnOp(I, [&](const AnyValue &V) -> AnyValue {
if (V.isPoison())
@@ -2260,6 +2258,15 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
});
}
+ void visitPtrToAddr(PtrToAddrInst &I) {
+ unsigned BitWidth = I.getType()->getScalarSizeInBits();
+ return visitUnOp(I, [&](const AnyValue &V) -> AnyValue {
+ if (V.isPoison())
+ return AnyValue::poison();
+ return V.asPointer().address().trunc(BitWidth);
+ });
+ }
+
void visitLoadInst(LoadInst &LI) {
auto RetVal = load(getValue(LI.getPointerOperand()), LI.getAlign(),
LI.getType(), LI.hasMetadata(LLVMContext::MD_noundef));
More information about the llvm-commits
mailing list