Files
sx/examples/expected/1659-platform-asm-x86-symbol-operand.ir
agra 066ba54346 feat(asm): portable symbol refs — auto-inject :c operand modifier
A `%[name]` that references a symbol ("s") operand without an explicit
modifier now lowers to `${N:c}` (LLVM 'bare constant — no punctuation')
instead of `${N}`. This makes `bl %[fn]` / `call %[fn]` portable across
targets with no per-arch knowledge: x86 would otherwise render `$cb`
(an invalid call target, requiring a hand-written `:P`); aarch64 is
unaffected. Verified `:c` is equivalent to `:P` for x86-64 calls (both
emit R_X86_64_PLT32), and correct for branch targets, RIP-relative
addressing, and `$`-prefixed absolute immediates.

renderAsmTemplate injects `:c` only for symbol operands lacking an
explicit modifier (asmNamedIsSymbol helper); an explicit `%[name:X]`
still wins (escape hatch). x86 example 1659 drops its `:P` for the same
plain `%[fn]` as aarch64 1656. Snapshots regen to `${N:c}`. zig build
test green (668 corpus, 446 unit).
2026-06-16 09:04:23 +03:00

35 lines
898 B
Plaintext

; Function Attrs: nounwind
define i64 @cb(i64 %0) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
ret i64 %add
}
; Function Attrs: nounwind
define internal i64 @tramp(i64 %0) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%asm = call i64 asm sideeffect "call ${2:c}", "={rax},{rdi},s,~{rcx},~{rdx},~{rsi},~{r8},~{r9},~{r10},~{r11},~{memory}"(i64 %load, ptr @cb)
ret i64 %asm
}
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%call = call i64 @tramp(i64 41)
%icmp = icmp ne i64 %call, 42
br i1 %icmp, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
ret i32 1
if.merge.1: ; preds = %entry
ret i32 0
}