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:
@@ -6,9 +6,9 @@ function u0:0(i8) -> i8 fast {
|
||||
block0(v0: i8):
|
||||
v1 = iconst.i8 0
|
||||
v2 = isub v1, v0
|
||||
; check: v3 = uextend.i32 v0
|
||||
; nextln: v5 = iconst.i32 0
|
||||
; nextln = isub v5, v3
|
||||
; nextln = ireduce.i8 v4
|
||||
; check: v4 = uextend.i32 v0
|
||||
; nextln: v6 = iconst.i32 0
|
||||
; nextln: v5 = isub v6, v4
|
||||
; nextln: v2 = ireduce.i8 v5
|
||||
return v2
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -58,4 +58,3 @@ block0(v0: i64):
|
||||
; nextln: v2 = iadd v0, v1
|
||||
; nextln: return v2
|
||||
; nextln: }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user