diff --git a/cranelift/filetests/filetests/isa/x86/pinned-reg.clif b/cranelift/filetests/filetests/isa/x86/pinned-reg.clif new file mode 100644 index 0000000000..b8a16d4eb4 --- /dev/null +++ b/cranelift/filetests/filetests/isa/x86/pinned-reg.clif @@ -0,0 +1,74 @@ +test compile + +set enable_pinned_reg=true +set use_pinned_reg_as_heap_base=true +set opt_level=best + +target x86_64 + +; regex: V=v\d+ + +; r15 is the pinned heap register. It must not be rewritten, so it must not be +; used as a tied output register. +function %tied_input() -> i64 system_v { +ebb0: + v1 = get_pinned_reg.i64 + v2 = iadd_imm v1, 42 + return v2 +} + +; check: ,%r15] +; sameln: v1 = get_pinned_reg.i64 +; nextln: regmove v1, %r15 -> %rax +; nextln: ,%rax] +; sameln: iadd_imm v1, 42 + +;; It musn't be used even if this is a tied input used twice. +function %tied_twice() -> i64 system_v { +ebb0: + v1 = get_pinned_reg.i64 + v2 = iadd v1, v1 + return v2 +} + +; check: ,%r15] +; sameln: v1 = get_pinned_reg.i64 +; nextln: regmove v1, %r15 -> %rax +; nextln: ,%rax] +; sameln: iadd v1, v1 + +function %uses() -> i64 system_v { +ebb0: + v1 = get_pinned_reg.i64 + v2 = iadd_imm v1, 42 + v3 = get_pinned_reg.i64 + v4 = iadd v2, v3 + return v4 +} + +; check: ,%r15] +; sameln: v1 = get_pinned_reg.i64 +; nextln: regmove v1, %r15 -> %rax +; nextln: ,%rax] +; sameln: iadd_imm v1, 42 +; nextln: ,%r15 +; sameln: v3 = get_pinned_reg.i64 +; nextln: ,%rax] +; sameln: iadd v2, v3 + +; When the pinned register is used as the heap base, the final load instruction +; must use the %r15 register, since x86 implements the complex addressing mode. +function u0:1(i64 vmctx) -> i64 system_v { + gv0 = vmctx + heap0 = static gv0, min 0x000a_0000, bound 0x0001_0000_0000, offset_guard 0x8000_0000, index_type i32 + +ebb0(v42: i64): + v5 = iconst.i32 42 + v6 = heap_addr.i64 heap0, v5, 0 + v7 = load.i64 v6 + return v7 +} + +; check: ,%r15] +; sameln: $(heap_base=$V) = get_pinned_reg.i64 +; nextln: load_complex.i64 $heap_base+