Files
wasmtime/cranelift/filetests/verifier/flags.cton
Dan Gohman 6606b88136 Optimize immediates and compare and branch sequences (#286)
* Add a pre-opt optimization to change constants into immediates.

This converts 'iadd' + 'iconst' into 'iadd_imm', and so on.

* Optimize away redundant `bint` instructions.

Cretonne has a concept of "Testable" values, which can be either boolean
or integer. When the an instruction needing a "Testable" value receives
the result of a `bint`, converting boolean to integer, eliminate the
`bint`, as it's redundant.

* Postopt: Optimize using CPU flags.

This introduces a post-legalization optimization pass which converts
compare+branch sequences to use flags values on CPUs which support it.

* Define a form of x86's `urm` that doesn't clobber FLAGS.

movzbl/movsbl/etc. don't clobber FLAGS; define a form of the `urm`
recipe that represents this.

* Implement a DCE pass.

This pass deletes instructions with no side effects and no results that
are used.

* Clarify ambiguity about "32-bit" and "64-bit" in comments.

* Add x86 encodings for icmp_imm.

* Add a testcase for postopt CPU flags optimization.

This covers the basic functionality of transforming compare+branch
sequences to use CPU flags.

* Pattern-match irsub_imm in preopt.
2018-03-30 12:30:07 -07:00

77 lines
2.6 KiB
Plaintext

test verifier
isa intel
; Simple, correct use of CPU flags.
function %simple(i32) -> i32 {
ebb0(v0: i32):
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op2seti_abcd#490] v2 = trueif ugt v1
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
[Op1ret#c3] return v3
}
; Overlapping flag values of different types.
function %overlap(i32, f32) -> i32 {
ebb0(v0: i32, v1: f32):
[Op1rcmp#39] v2 = ifcmp v0, v0
[Op2fcmp#42e] v3 = ffcmp v1, v1
[Op2setf_abcd#490] v4 = trueff gt v3 ; error: conflicting live CPU flags: v2 and v3
[Op2seti_abcd#490] v5 = trueif ugt v2
[Op1rr#21] v6 = band v4, v5
[Op2urm_noflags_abcd#4b6] v7 = bint.i32 v6
[Op1ret#c3] return v7
}
; CPU flags clobbered by arithmetic.
function %clobbered(i32) -> i32 {
ebb0(v0: i32):
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op1rr#01] v2 = iadd v0, v0 ; error: encoding clobbers live CPU flags in v1
[Op2seti_abcd#490] v3 = trueif ugt v1
[Op2urm_noflags_abcd#4b6] v4 = bint.i32 v3
[Op1ret#c3] return v4
}
; CPU flags not clobbered by load.
function %live_across_load(i32) -> i32 {
ebb0(v0: i32):
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op1ld#8b] v2 = load.i32 v0
[Op2seti_abcd#490] v3 = trueif ugt v1
[Op2urm_noflags_abcd#4b6] v4 = bint.i32 v3
[Op1ret#c3] return v4
}
; Correct use of CPU flags across EBB.
function %live_across_ebb(i32) -> i32 {
ebb0(v0: i32):
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op1jmpb#eb] jump ebb1
ebb1:
[Op2seti_abcd#490] v2 = trueif ugt v1
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
[Op1ret#c3] return v3
}
function %live_across_ebb_backwards(i32) -> i32 {
ebb0(v0: i32):
[Op1jmpb#eb] jump ebb2
ebb1:
[Op2seti_abcd#490] v2 = trueif ugt v1
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
[Op1ret#c3] return v3
ebb2:
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op1jmpb#eb] jump ebb1
}
; Flags live into loop.
function %live_into_loop(i32) -> i32 {
ebb0(v0: i32):
[Op1rcmp#39] v1 = ifcmp v0, v0
[Op1jmpb#eb] jump ebb1
ebb1:
[Op2seti_abcd#490] v2 = trueif ugt v1
[Op1jmpb#eb] jump ebb1
}