cranelift: Port most of simple_preopt.rs over to the peepmatic DSL

This ports all of the identity, no-op, simplification, and canonicalization
related optimizations over from being hand-coded to the `peepmatic` DSL. This
does not handle the branch-to-branch optimizations or most of the
divide-by-constant optimizations.
This commit is contained in:
Nick Fitzgerald
2020-04-28 16:43:32 -07:00
parent 18663fede9
commit 090d1c2d32
20 changed files with 1289 additions and 488 deletions

View File

@@ -7,14 +7,13 @@ function %indir_udiv32(i32) -> i32 {
block0(v0: i32):
v1 = iconst.i32 7
v2 = udiv v0, v1
; check: iconst.i32 7
; check: iconst.i32 0x2492_4925
; check: umulhi v0, v3
; check: isub v0, v4
; check: ushr_imm v5, 1
; check: iadd v6, v4
; check: v8 = ushr_imm v7, 2
; check: v2 -> v8
; check: v4 = iconst.i32 0x2492_4925
; nextln: v5 = umulhi v0, v4
; nextln: v6 = isub v0, v5
; nextln: v7 = ushr_imm v6, 1
; nextln: v8 = iadd v7, v5
; nextln: v9 = ushr_imm v8, 2
; nextln: v2 -> v9
return v2
}
@@ -22,13 +21,12 @@ function %indir_sdiv32(i32) -> i32 {
block0(v0: i32):
v1 = iconst.i32 -17
v2 = sdiv v0, v1
; check: iconst.i32 -17
; check: iconst.i32 0xffff_ffff_8787_8787
; check: smulhi v0, v3
; check: sshr_imm v4, 3
; check: ushr_imm v5, 31
; check: v7 = iadd v5, v6
; check: v2 -> v7
; check: v4 = iconst.i32 0xffff_ffff_8787_8787
; nextln: v5 = smulhi v0, v4
; nextln: v6 = sshr_imm v5, 3
; nextln: v7 = ushr_imm v6, 31
; nextln: v8 = iadd v6, v7
; nextln: v2 -> v8
return v2
}
@@ -36,11 +34,10 @@ function %indir_udiv64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 1337
v2 = udiv v0, v1
; check: iconst.i64 1337
; check: iconst.i64 0xc411_9d95_2866_a139
; check: umulhi v0, v3
; check: v5 = ushr_imm v4, 10
; check: v2 -> v5
; check: v4 = iconst.i64 0xc411_9d95_2866_a139
; nextln: v5 = umulhi v0, v4
; nextln: v6 = ushr_imm v5, 10
; nextln: v2 -> v6
return v2
}
@@ -48,12 +45,11 @@ function %indir_sdiv64(i64) -> i64 {
block0(v0: i64):
v1 = iconst.i64 -90210
v2 = sdiv v0, v1
; check: iconst.i64 0xffff_ffff_fffe_9f9e
; check: iconst.i64 0xd181_4ee8_939c_b8bb
; check: smulhi v0, v3
; check: sshr_imm v4, 14
; check: ushr_imm v5, 63
; check: v7 = iadd v5, v6
; check: v2 -> v7
; check: v4 = iconst.i64 0xd181_4ee8_939c_b8bb
; nextln: v5 = smulhi v0, v4
; nextln: v6 = sshr_imm v5, 14
; nextln: v7 = ushr_imm v6, 63
; nextln: v8 = iadd v6, v7
; nextln: v2 -> v8
return v2
}

View File

@@ -0,0 +1,22 @@
test simple_preopt
target x86_64
function u0:2(i64 , i64) {
gv1 = load.i64 notrap aligned gv0
heap0 = static gv1
block0(v0: i64, v1: i64):
v16 = iconst.i32 6
v17 = heap_addr.i64 heap0, v16, 1
v18 = load.i32 v17
v19 = iconst.i32 4
v20 = icmp ne v18, v19
v21 = bint.i32 v20
brnz v21, block2
jump block4
block4:
jump block1
block2:
jump block1
block1:
return
}

View File

@@ -58,4 +58,3 @@ block0(v0: i64):
; nextln: v2 = iadd v0, v1
; nextln: return v2
; nextln: }

View File

@@ -44,6 +44,37 @@ block0(v0: i32):
; nextln: return v3
; nextln: }
function %ifcmp_imm(i32) -> i32 {
block0(v0: i32):
v1 = iconst.i32 2
v2 = ifcmp v0, v1
brif eq v2, block1
jump block2
block1:
v3 = iconst.i32 1
return v3
block2:
v4 = iconst.i32 2
return v4
}
; sameln: function %ifcmp_imm
; nextln: block0(v0: i32):
; nextln: v1 = iconst.i32 2
; nextln: v2 = ifcmp_imm v0, 2
; nextln: brif eq v2, block1
; nextln: jump block2
; nextln:
; nextln: block1:
; nextln: v3 = iconst.i32 1
; nextln: return v3
; nextln:
; nextln: block2:
; nextln: v4 = iconst.i32 2
; nextln: return v4
; nextln: }
function %brz_bint(i32) {
block0(v0: i32):
v3 = icmp_imm slt v0, 0

View File

@@ -0,0 +1,17 @@
test simple_preopt
target x86_64
;; The `isub` is a no-op, but we can't replace the whole `isub` instruction with
;; its `v2` operand's instruction because `v2` is one of many results. Instead,
;; we need to make an alias `v3 -> v2`.
function %replace_inst_with_alias() -> i32 {
block0:
v0 = iconst.i32 0
v1, v2 = x86_smulx v0, v0
v3 = isub v2, v0
; check: v0 = iconst.i32 0
; nextln: v1, v2 = x86_smulx v0, v0
; nextln: v3 -> v2
return v3
}