Skip to content

llvm: bind LLVM 22 pointer address extraction - #53

Merged
xushiwei merged 1 commit into
xgo-dev:xgofrom
zhouguangyuan0718:codex/llvm22-ptrtoaddr
Sep 7, 2026
Merged

llvm: bind LLVM 22 pointer address extraction#53
xushiwei merged 1 commit into
xgo-dev:xgofrom
zhouguangyuan0718:codex/llvm22-ptrtoaddr

Conversation

@zhouguangyuan0718

Copy link
Copy Markdown

LLVM 22's ptrtoaddr observes a pointer's address without exposing its provenance. Add Builder.CreatePtrToAddr using the module DataLayout to select the address-space index width, plus the opcode and constant-expression constructor so consumers can preserve the operation when cloning IR.

The new APIs are available only for LLVM 22. The small C++ bridge is version guarded because the LLVM C API exposes the opcode but lacks dedicated builder and constant constructors.

Validation on macOS arm64:

  • go test ./... with LLVM 22.1.8.
  • go test -tags=llvm21 ./... and go test -tags=llvm19 ./....
  • Regression coverage verifies scalar/vector address extraction, 64-bit pointers with 32-bit address-space index width, constant-expression parsing round trips, and the O2 provenance distinction from ptrtoint.

Other platforms and LLVM versions remain subject to CI.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: LLVM 22 ptrtoaddr bindings

Solid, well-scoped addition. It follows the repo's version-gated split-file convention (mirroring switch_llvm22.go), the C++ shim is guarded with #if LLVM_VERSION_MAJOR >= 22, doc comments are accurate against LLVM's ptrtoaddr semantics, and the tests are strong — TestPtrToAddrDoesNotExposeProvenance empirically proves the provenance distinction from ptrtoint by running default<O2> and asserting the load is eliminated only for ptrtoaddr.

Findings are inline. A few cross-file notes below.

Build-tag / pre-22 contract (worth a maintainer decision). Unlike switch, there is no ptrtoaddr_pre22.go stub. ptrtoaddr_llvm22.go builds under the default tag set (!llvm14 && ... && !llvm21), so if someone builds with no version tag against LLVM ≤ 21 headers, this file still compiles and references C.LLVMPtrToAddr (missing from the older enum → compile error) plus the C++ helpers (guarded out → link error). This matches the pre-existing "default means latest/22" assumption in llvm_config_llvm22.go, so it may be acceptable — but the Go file keys off build tags while the C++ keys off LLVM_VERSION_MAJOR, and the two disagree in that one case. Consider either documenting the default-tag contract or adding a ptrtoaddr_pre22.go stub for parity with switch.

unwrap<Constant> in ConstPtrToAddr (informational). LLVMGoConstPtrToAddr uses unwrap<Constant>(V) (i.e. cast<Constant>), which in LLVM's default NDEBUG build is an unchecked downcast — passing a non-Constant value is UB. This is identical to every other Const* binding (e.g. LLVMConstPtrToInt, IRBindings.cpp) and the upstream LLVM-C trust model, so no change is required; noted only for completeness.

Performance and documentation passes found no issues.

Comment thread PtrToAddrBindings.h
@@ -0,0 +1,18 @@
#ifndef LLVM_BINDINGS_GO_PTRTOADDR_H

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Missing LLVM license header in new C++ files

Every existing binding file (IRBindings.h, SupportBindings.h, TargetBindings.h, etc.) opens with the standard //===- ... ===// Apache-2.0-WITH-LLVM-exception header block. Both PtrToAddrBindings.h and PtrToAddrBindings.cpp omit it. For an LLVM sub-project this header is effectively mandatory — please add the same block to both new files.

Comment thread PtrToAddrBindings.cpp
@@ -0,0 +1,18 @@
#include "PtrToAddrBindings.h"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Missing LLVM license header

Same as the header file: this .cpp is missing the standard //===- ... ===// Apache-2.0-WITH-LLVM-exception block that every other binding source in the repo carries.

Comment thread ptrtoaddr_llvm22.go
import "C"
import "unsafe"

const PtrToAddr Opcode = C.LLVMPtrToAddr

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] PtrToAddr Opcode const lives apart from the others in ir.go

All other Opcode constants — including the closely related PtrToInt Opcode = C.LLVMPtrToInt — live in the single const block in ir.go, so placing PtrToAddr here breaks discoverability. Keeping it separate is a genuine necessity (the enum only exists in the LLVM 22 C API, and ir.go is compiled unconditionally). Consider a one-line comment noting it is kept here rather than in ir.go because C.LLVMPtrToAddr only exists in LLVM 22+, to save the next maintainer the investigation.

Comment thread ptrtoaddr_llvm22_test.go
fn := AddFunction(mod, tc.name, FunctionType(tc.addr, []Type{tc.ptr}, false))
builder.SetInsertPointAtEnd(ctx.AddBasicBlock(fn, "entry"))
addr := builder.CreatePtrToAddr(fn.Param(0), "addr")
if addr.Type() != tc.addr || addr.InstructionOpcode() != PtrToAddr {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Combined assertion shares one error message

This check tests two distinct properties (result type and opcode) but reports a single "unexpected ptrtoaddr" message. On failure the developer can't immediately tell whether the type or the opcode was wrong. Splitting into two checks, or including the expected-vs-actual type/opcode in the message, would improve diagnosability. Minor — the printed addr.String() already gives a strong hint.

@xushiwei
xushiwei merged commit 6cc563a into xgo-dev:xgo Sep 7, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants