Files
sx/examples/expected/1656-platform-asm-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

29 lines
789 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 " stp x29, x30, [sp, #-16]!\0A mov x0, ${1}\0A bl ${2:c}\0A mov ${0}, x0\0A ldp x29, x30, [sp], #16\0A", "=r,r,s,~{x0},~{x30},~{memory}"(i64 %load, ptr @cb)
ret i64 %asm
}
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%call = call i64 @tramp(i64 41)
%ca.tr = trunc i64 %call to i32
ret i32 %ca.tr
}