Files
wasmtime/cranelift/filetests/filetests/isa/aarch64/call.clif
Chris Fallin e95ffe4413 Fix StructReturn handling: properly mark the clobber, and offset actual rets. (#5023)
* Fix StructReturn handling: properly mark the clobber, and offset actual rets.

The legalization of `StructReturn` was causing issues in the new
call-handling code: the `StructReturn` ret was included in the `SigData` as
if it were an actual CLIF-level return value, but it is not.

Prior to using regalloc constraints for return values, we
unconditionally included rax (or the architecture's usual return
register) as a def, so it would be properly handled as "clobbered" by
the regalloc. With the new scheme, we include defs on the call only for
CLIF-level outputs. Callees with `StructReturn` args were thus not known
to clobber the return-value register, and values might be corrupted.

This PR updates the code to include a `StructReturn` ret as a clobber
rather than a returned value in the relevant spots. I observed it
causing saves/restores of rax in some CLIF that @bjorn3 provided me, but
I was having difficulty minimizing this into a test-case that I would be
comfortable including as a precise-output case (including the whole
thing verbatim would lock down a bunch of other irrelevant details and
cause test-update noise later). If we can find a more minimized example
I'm happy to include it as a filetest.

Fixes #5018.
2022-10-07 00:14:38 +00:00

501 lines
8.8 KiB
Plaintext

test compile precise-output
set unwind_info=false
set enable_probestack=false
target aarch64
function %f1(i64) -> i64 {
fn0 = %g(i64) -> i64
block0(v0: i64):
v1 = call fn0(v0)
return v1
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; ldr x4, 8 ; b 12 ; data TestCase(%g) + 0
; blr x4
; ldp fp, lr, [sp], #16
; ret
function %f2(i32) -> i64 {
fn0 = %g(i32 uext) -> i64
block0(v0: i32):
v1 = call fn0(v0)
return v1
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; ldr x4, 8 ; b 12 ; data TestCase(%g) + 0
; blr x4
; ldp fp, lr, [sp], #16
; ret
function %f3(i32) -> i32 uext {
block0(v0: i32):
return v0
}
; block0:
; ret
function %f4(i32) -> i64 {
fn0 = %g(i32 sext) -> i64
block0(v0: i32):
v1 = call fn0(v0)
return v1
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; ldr x4, 8 ; b 12 ; data TestCase(%g) + 0
; blr x4
; ldp fp, lr, [sp], #16
; ret
function %f5(i32) -> i32 sext {
block0(v0: i32):
return v0
}
; block0:
; ret
function %f6(i8) -> i64 {
fn0 = %g(i32, i32, i32, i32, i32, i32, i32, i32, i8 sext) -> i64
block0(v0: i8):
v1 = iconst.i32 42
v2 = call fn0(v1, v1, v1, v1, v1, v1, v1, v1, v0)
return v2
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x8, x0
; sub sp, sp, #16
; virtual_sp_offset_adjust 16
; movz x0, #42
; movz x1, #42
; movz x2, #42
; movz x3, #42
; movz x4, #42
; movz x5, #42
; movz x6, #42
; movz x7, #42
; strb w8, [sp]
; ldr x8, 8 ; b 12 ; data TestCase(%g) + 0
; blr x8
; add sp, sp, #16
; virtual_sp_offset_adjust -16
; ldp fp, lr, [sp], #16
; ret
function %f7(i8) -> i32, i32, i32, i32, i32, i32, i32, i32, i8 sext {
block0(v0: i8):
v1 = iconst.i32 42
return v1, v1, v1, v1, v1, v1, v1, v1, v0
}
; block0:
; mov x8, x0
; mov x13, x1
; movz x0, #42
; movz x1, #42
; movz x2, #42
; movz x3, #42
; movz x4, #42
; movz x5, #42
; movz x6, #42
; movz x7, #42
; mov x11, x8
; strb w11, [x13]
; ret
function %f8() {
fn0 = %g0() -> f32
fn1 = %g1() -> f64
fn2 = %g2()
fn3 = %g3(f32)
fn4 = %g4(f64)
block0:
v0 = call fn0()
v1 = call fn1()
v2 = call fn1()
call fn2()
call fn3(v0)
call fn4(v1)
call fn4(v2)
return
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; sub sp, sp, #48
; block0:
; ldr x9, 8 ; b 12 ; data TestCase(%g0) + 0
; blr x9
; str q0, [sp, #32]
; ldr x9, 8 ; b 12 ; data TestCase(%g1) + 0
; blr x9
; str q0, [sp, #16]
; ldr x9, 8 ; b 12 ; data TestCase(%g1) + 0
; blr x9
; str q0, [sp]
; ldr x9, 8 ; b 12 ; data TestCase(%g2) + 0
; blr x9
; ldr x10, 8 ; b 12 ; data TestCase(%g3) + 0
; ldr q0, [sp, #32]
; blr x10
; ldr x11, 8 ; b 12 ; data TestCase(%g4) + 0
; ldr q0, [sp, #16]
; blr x11
; ldr x12, 8 ; b 12 ; data TestCase(%g4) + 0
; ldr q0, [sp]
; blr x12
; add sp, sp, #48
; ldp fp, lr, [sp], #16
; ret
function %f9() {
fn0 = %g0() -> i8x16
fn1 = %g1()
fn2 = %g2(i8x16)
block0:
v0 = call fn0()
v1 = call fn0()
v2 = call fn0()
call fn1()
call fn2(v0)
call fn2(v1)
call fn2(v2)
return
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; sub sp, sp, #48
; block0:
; ldr x9, 8 ; b 12 ; data TestCase(%g0) + 0
; blr x9
; str q0, [sp, #32]
; ldr x9, 8 ; b 12 ; data TestCase(%g0) + 0
; blr x9
; str q0, [sp, #16]
; ldr x9, 8 ; b 12 ; data TestCase(%g0) + 0
; blr x9
; str q0, [sp]
; ldr x9, 8 ; b 12 ; data TestCase(%g1) + 0
; blr x9
; ldr x10, 8 ; b 12 ; data TestCase(%g2) + 0
; ldr q0, [sp, #32]
; blr x10
; ldr x11, 8 ; b 12 ; data TestCase(%g2) + 0
; ldr q0, [sp, #16]
; blr x11
; ldr x12, 8 ; b 12 ; data TestCase(%g2) + 0
; ldr q0, [sp]
; blr x12
; add sp, sp, #48
; ldp fp, lr, [sp], #16
; ret
function %f10() {
fn0 = %g0() -> f32
fn1 = %g1() -> f64
fn2 = %g2() -> i8x16
fn3 = %g3()
fn4 = %g4(f32)
fn5 = %g5(f64)
fn6 = %g6(i8x16)
block0:
v0 = call fn0()
v1 = call fn1()
v2 = call fn2()
call fn3()
call fn4(v0)
call fn5(v1)
call fn6(v2)
return
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; sub sp, sp, #48
; block0:
; ldr x9, 8 ; b 12 ; data TestCase(%g0) + 0
; blr x9
; str q0, [sp, #32]
; ldr x9, 8 ; b 12 ; data TestCase(%g1) + 0
; blr x9
; str q0, [sp, #16]
; ldr x9, 8 ; b 12 ; data TestCase(%g2) + 0
; blr x9
; str q0, [sp]
; ldr x9, 8 ; b 12 ; data TestCase(%g3) + 0
; blr x9
; ldr x10, 8 ; b 12 ; data TestCase(%g4) + 0
; ldr q0, [sp, #32]
; blr x10
; ldr x11, 8 ; b 12 ; data TestCase(%g5) + 0
; ldr q0, [sp, #16]
; blr x11
; ldr x12, 8 ; b 12 ; data TestCase(%g6) + 0
; ldr q0, [sp]
; blr x12
; add sp, sp, #48
; ldp fp, lr, [sp], #16
; ret
function %f11(i128, i64) -> i64 {
block0(v0: i128, v1: i64):
v2, v3 = isplit v0
return v3
}
; block0:
; mov x0, x1
; ret
function %f11_call(i64) -> i64 {
fn0 = %f11(i128, i64) -> i64
block0(v0: i64):
v1 = iconst.i64 42
v2 = iconcat v1, v0
v3 = call fn0(v2, v1)
return v3
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x1, x0
; movz x0, #42
; movz x2, #42
; ldr x7, 8 ; b 12 ; data TestCase(%f11) + 0
; blr x7
; ldp fp, lr, [sp], #16
; ret
function %f12(i64, i128) -> i64 {
block0(v0: i64, v1: i128):
v2, v3 = isplit v1
return v2
}
; block0:
; mov x0, x2
; ret
function %f12_call(i64) -> i64 {
fn0 = %f12(i64, i128) -> i64
block0(v0: i64):
v1 = iconst.i64 42
v2 = iconcat v0, v1
v3 = call fn0(v1, v2)
return v3
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x2, x0
; movz x3, #42
; movz x0, #42
; ldr x7, 8 ; b 12 ; data TestCase(%f12) + 0
; blr x7
; ldp fp, lr, [sp], #16
; ret
function %f13(i64, i128) -> i64 apple_aarch64 {
block0(v0: i64, v1: i128):
v2, v3 = isplit v1
return v2
}
; block0:
; mov x0, x1
; ret
function %f13_call(i64) -> i64 apple_aarch64 {
fn0 = %f13(i64, i128) -> i64 apple_aarch64
block0(v0: i64):
v1 = iconst.i64 42
v2 = iconcat v0, v1
v3 = call fn0(v1, v2)
return v3
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x1, x0
; movz x2, #42
; movz x0, #42
; ldr x7, 8 ; b 12 ; data TestCase(%f13) + 0
; blr x7
; ldp fp, lr, [sp], #16
; ret
function %f14(i128, i128, i128, i64, i128) -> i128 {
block0(v0: i128, v1: i128, v2: i128, v3: i64, v4: i128):
return v4
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; ldr x0, [fp, #16]
; ldr x1, [fp, #24]
; ldp fp, lr, [sp], #16
; ret
function %f14_call(i128, i64) -> i128 {
fn0 = %f14(i128, i128, i128, i64, i128) -> i128
block0(v0: i128, v1: i64):
v2 = call fn0(v0, v0, v0, v1, v0)
return v2
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x6, x2
; sub sp, sp, #16
; virtual_sp_offset_adjust 16
; str x0, [sp]
; mov x4, x0
; str x1, [sp, #8]
; mov x5, x1
; ldr x12, 8 ; b 12 ; data TestCase(%f14) + 0
; mov x0, x4
; mov x2, x4
; mov x1, x5
; mov x3, x5
; blr x12
; add sp, sp, #16
; virtual_sp_offset_adjust -16
; ldp fp, lr, [sp], #16
; ret
function %f15(i128, i128, i128, i64, i128) -> i128 apple_aarch64{
block0(v0: i128, v1: i128, v2: i128, v3: i64, v4: i128):
return v4
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; ldr x0, [fp, #16]
; ldr x1, [fp, #24]
; ldp fp, lr, [sp], #16
; ret
function %f15_call(i128, i64) -> i128 apple_aarch64 {
fn0 = %f15(i128, i128, i128, i64, i128) -> i128 apple_aarch64
block0(v0: i128, v1: i64):
v2 = call fn0(v0, v0, v0, v1, v0)
return v2
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x6, x2
; sub sp, sp, #16
; virtual_sp_offset_adjust 16
; str x0, [sp]
; mov x4, x0
; str x1, [sp, #8]
; mov x5, x1
; ldr x12, 8 ; b 12 ; data TestCase(%f15) + 0
; mov x0, x4
; mov x2, x4
; mov x1, x5
; mov x3, x5
; blr x12
; add sp, sp, #16
; virtual_sp_offset_adjust -16
; ldp fp, lr, [sp], #16
; ret
function %f16() -> i32, i32 wasmtime_system_v {
block0:
v0 = iconst.i32 0
v1 = iconst.i32 1
return v0, v1
}
; block0:
; mov x11, x0
; movz x0, #0
; movz x7, #1
; str w7, [x11]
; ret
function %f17(i64 sret) {
block0(v0: i64):
v1 = iconst.i64 42
store v1, v0
return
}
; block0:
; mov x5, x8
; movz x4, #42
; str x4, [x8]
; ret
function %f18(i64) -> i64 {
fn0 = %g(i64 sret) -> i64
block0(v0: i64):
v1 = call fn0(v0)
return v1
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; block0:
; mov x8, x0
; ldr x4, 8 ; b 12 ; data TestCase(%g) + 0
; blr x4
; ldp fp, lr, [sp], #16
; ret
function %f18(i64 sret) {
fn0 = %g(i64 sret)
block0(v0: i64):
call fn0(v0)
return
}
; stp fp, lr, [sp, #-16]!
; mov fp, sp
; str x24, [sp, #-16]!
; block0:
; mov x24, x8
; ldr x4, 8 ; b 12 ; data TestCase(%g) + 0
; blr x4
; mov x8, x24
; ldr x24, [sp], #16
; ldp fp, lr, [sp], #16
; ret