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).
35 lines
898 B
Plaintext
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
|
|
}
|