* x64: clean up regalloc-related semantics on several instructions. This PR removes all uses of "modify" operands on instructions in the x64 backend, and also removes all uses of "pinned vregs", or vregs that are explicitly tied to particular physical registers. In place of both of these mechanisms, which are legacies of the old regalloc design and supported via compatibility code, the backend now uses operand constraints. This is more flexible as it allows the regalloc to see the liveranges and constraints without "reverse-engineering" move instructions. Eventually, after removing all such uses (including in other backends and by the ABI code), we can remove the compatibility code in regalloc2, significantly simplifying its liverange-construction frontend and thus allowing for higher confidence in correctness as well as possibly a bit more compilation speed. Curiously, there are a few extra move instructions now; they are likely poor splitting decisions and I can try to chase these down later. * Fix cranelift-codegen tests. * Review feedback.
285 lines
4.2 KiB
Plaintext
285 lines
4.2 KiB
Plaintext
test compile precise-output
|
|
target x86_64
|
|
|
|
function %f0(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = icmp eq v0, v1
|
|
brnz v2, block1
|
|
jump block2
|
|
|
|
block1:
|
|
v3 = iconst.i32 1
|
|
return v3
|
|
|
|
block2:
|
|
v4 = iconst.i32 2
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpl %esi, %edi
|
|
; jz label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; movl $2, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f1(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = icmp eq v0, v1
|
|
brz v2, block1
|
|
jump block2
|
|
|
|
block1:
|
|
v3 = iconst.i32 1
|
|
return v3
|
|
|
|
block2:
|
|
v4 = iconst.i32 2
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpl %esi, %edi
|
|
; jnz label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; movl $2, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f2(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = ifcmp v0, v1
|
|
brif eq v2, block1
|
|
jump block2
|
|
|
|
block1:
|
|
v3 = iconst.i32 1
|
|
return v3
|
|
|
|
block2:
|
|
v4 = iconst.i32 2
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpl %esi, %edi
|
|
; jz label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; movl $2, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f3(f32, f32) -> i32 {
|
|
block0(v0: f32, v1: f32):
|
|
v2 = ffcmp v0, v1
|
|
brff eq v2, block1
|
|
jump block2
|
|
|
|
block1:
|
|
v3 = iconst.i32 1
|
|
return v3
|
|
|
|
block2:
|
|
v4 = iconst.i32 2
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; ucomiss %xmm1, %xmm0
|
|
; jp label2
|
|
; jnz label2; j label1
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; movl $2, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f4(f32, f32) -> b1 {
|
|
block0(v0: f32, v1: f32):
|
|
v2 = fcmp eq v0, v1
|
|
brz v2, block1
|
|
jump block2
|
|
block1:
|
|
v3 = bconst.b1 true
|
|
return v3
|
|
block2:
|
|
v4 = bconst.b1 false
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; ucomiss %xmm1, %xmm0
|
|
; jp label1
|
|
; jnz label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; xorl %eax, %eax, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f4(f32, f32) -> b1 {
|
|
block0(v0: f32, v1: f32):
|
|
v2 = fcmp ne v0, v1
|
|
brz v2, block1
|
|
jump block2
|
|
block1:
|
|
v3 = bconst.b1 true
|
|
return v3
|
|
block2:
|
|
v4 = bconst.b1 false
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; ucomiss %xmm1, %xmm0
|
|
; jp label2
|
|
; jnz label2; j label1
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; xorl %eax, %eax, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
|
|
function %f5(i32) -> b1 {
|
|
jt0 = jump_table [block1, block2]
|
|
|
|
block0(v0: i32):
|
|
br_table v0, block1, jt0
|
|
|
|
block1:
|
|
v1 = bconst.b1 true
|
|
return v1
|
|
|
|
block2:
|
|
v2 = bconst.b1 false
|
|
return v2
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpl $2, %edi
|
|
; br_table %rdi, %r9, %r10
|
|
; block1:
|
|
; jmp label3
|
|
; block2:
|
|
; jmp label3
|
|
; block3:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block4:
|
|
; xorl %eax, %eax, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f6(i64) -> b1 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i64 0
|
|
v2 = icmp slt v0, v1
|
|
brnz v2, block1
|
|
jump block2
|
|
block1:
|
|
v3 = bconst.b1 true
|
|
return v3
|
|
block2:
|
|
v4 = bconst.b1 false
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpq $0, %rdi
|
|
; jl label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; xorl %eax, %eax, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|
|
function %f7(i32) -> b1 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 0
|
|
v2 = icmp slt v0, v1
|
|
brnz v2, block1
|
|
jump block2
|
|
block1:
|
|
v3 = bconst.b1 true
|
|
return v3
|
|
block2:
|
|
v4 = bconst.b1 false
|
|
return v4
|
|
}
|
|
|
|
; pushq %rbp
|
|
; movq %rsp, %rbp
|
|
; block0:
|
|
; cmpl $0, %edi
|
|
; jl label1; j label2
|
|
; block1:
|
|
; movl $1, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
; block2:
|
|
; xorl %eax, %eax, %eax
|
|
; movq %rbp, %rsp
|
|
; popq %rbp
|
|
; ret
|
|
|