forked from bytecodealliance/wasmtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add splat simplify opt for various ops (bytecodealliance#6851)
* Add splat simplify opt for iadd, isub, imul, ineg & iabs * Add splat simplify opt for smulhi & hmulhi * Add splat simplify opt for band, bor & bxor * Add splat simplify opt for a few more ops namely, popcnt, smin, umin, smax, umax, sadd_sat, uadd_sat, ssub_sat & usub_sat * Add splat simplify opt for bnot * Add splat simplify opt for shift and rotate ops and avg_round as well * Remove splat simplify opt for certain ops because they don't support scalars. * Add lane_type to splat opts for shift/rotate Some of the wasmtime spec tests were failing without this * Remove splat simplify opt for avg_round because it doesn't support scalars.
- Loading branch information
1 parent
158d5c7
commit b32a9d8
Showing
2 changed files
with
293 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,74 @@ | ||
;; Lift a splat outside of an int-to-float conversion to try to open up | ||
;; For various ops lift a splat outside of the op to try to open up | ||
;; optimization opportunities with scalars. | ||
;; | ||
;; NB: this is also required for correctness at this time due to #6562 | ||
;; NB: for int-to-float conversion op this simplification is also | ||
;; required for correctness at this time due to #6562 | ||
(rule (simplify (fcvt_from_uint float_vector_ty (splat _ x))) | ||
(splat float_vector_ty (fcvt_from_uint (lane_type float_vector_ty) x))) | ||
(rule (simplify (fcvt_from_sint float_vector_ty (splat _ x))) | ||
(splat float_vector_ty (fcvt_from_sint (lane_type float_vector_ty) x))) | ||
|
||
(rule (simplify (band ty (splat ty x) (splat ty y))) | ||
(splat ty (band (lane_type ty) x y))) | ||
|
||
(rule (simplify (bor ty (splat ty x) (splat ty y))) | ||
(splat ty (bor (lane_type ty) x y))) | ||
|
||
(rule (simplify (bxor ty (splat ty x) (splat ty y))) | ||
(splat ty (bxor (lane_type ty) x y))) | ||
|
||
(rule (simplify (bnot ty (splat ty x))) | ||
(splat ty (bnot (lane_type ty) x))) | ||
|
||
(rule (simplify (iadd ty (splat ty x) (splat ty y))) | ||
(splat ty (iadd (lane_type ty) x y))) | ||
|
||
(rule (simplify (isub ty (splat ty x) (splat ty y))) | ||
(splat ty (isub (lane_type ty) x y))) | ||
|
||
(rule (simplify (imul ty (splat ty x) (splat ty y))) | ||
(splat ty (imul (lane_type ty) x y))) | ||
|
||
(rule (simplify (smulhi ty (splat ty x) (splat ty y))) | ||
(splat ty (smulhi (lane_type ty) x y))) | ||
|
||
(rule (simplify (umulhi ty (splat ty x) (splat ty y))) | ||
(splat ty (umulhi (lane_type ty) x y))) | ||
|
||
(rule (simplify (ineg ty (splat ty x))) | ||
(splat ty (ineg (lane_type ty) x))) | ||
|
||
(rule (simplify (iabs ty (splat ty x))) | ||
(splat ty (iabs (lane_type ty) x))) | ||
|
||
(rule (simplify (popcnt ty (splat ty x))) | ||
(splat ty (popcnt (lane_type ty) x))) | ||
|
||
(rule (simplify (smin ty (splat ty x) (splat ty y))) | ||
(splat ty (smin (lane_type ty) x y))) | ||
|
||
(rule (simplify (umin ty (splat ty x) (splat ty y))) | ||
(splat ty (umin (lane_type ty) x y))) | ||
|
||
(rule (simplify (smax ty (splat ty x) (splat ty y))) | ||
(splat ty (smax (lane_type ty) x y))) | ||
|
||
(rule (simplify (umax ty (splat ty x) (splat ty y))) | ||
(splat ty (umax (lane_type ty) x y))) | ||
|
||
;; The second operand of shift and rotate ops is | ||
;; scalar so splat opt applies only to the first | ||
(rule (simplify (rotl ty (splat ty x) y)) | ||
(splat ty (rotl (lane_type ty) x y))) | ||
|
||
(rule (simplify (rotr ty (splat ty x) y)) | ||
(splat ty (rotr (lane_type ty) x y))) | ||
|
||
(rule (simplify (ishl ty (splat ty x) y)) | ||
(splat ty (ishl (lane_type ty) x y))) | ||
|
||
(rule (simplify (ushr ty (splat ty x) y)) | ||
(splat ty (ushr (lane_type ty) x y))) | ||
|
||
(rule (simplify (sshr ty (splat ty x) y)) | ||
(splat ty (sshr (lane_type ty) x y))) |
225 changes: 225 additions & 0 deletions
225
cranelift/filetests/filetests/egraph/simd-splat-simplify.clif
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
test optimize | ||
set opt_level=speed | ||
target x86_64 | ||
|
||
function %band_splat_into_splat_band(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = band.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = band v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %bor_splat_into_splat_bor(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = bor.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = bor v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %bxor_splat_into_splat_bxor(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = bxor.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = bxor v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %bnot_splat_into_splat_bnot(i64) -> i64x2 { | ||
block0(v0: i64): | ||
v1 = splat.i64x2 v0 | ||
v2 = bnot.i64x2 v1 | ||
return v2 | ||
; check: v3 = bnot v0 | ||
; check: v4 = splat.i64x2 v3 | ||
; check: return v4 | ||
} | ||
|
||
function %iadd_splat_into_splat_iadd(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = iadd.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = iadd v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %isub_splat_into_splat_isub(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = isub.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = isub v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %imul_splat_into_splat_imul(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = imul.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = imul v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %smulhi_splat_into_splat_smulhi(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = smulhi.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = smulhi v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %umulhi_splat_into_splat_umulhi(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = umulhi.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = umulhi v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %ineg_splat_into_splat_ineg(i64) -> i64x2 { | ||
block0(v0: i64): | ||
v1 = splat.i64x2 v0 | ||
v2 = ineg.i64x2 v1 | ||
return v2 | ||
; check: v3 = ineg v0 | ||
; check: v4 = splat.i64x2 v3 | ||
; check: return v4 | ||
} | ||
|
||
function %iabs_splat_into_splat_iabs(i64) -> i64x2 { | ||
block0(v0: i64): | ||
v1 = splat.i64x2 v0 | ||
v2 = iabs.i64x2 v1 | ||
return v2 | ||
; check: v3 = iabs v0 | ||
; check: v4 = splat.i64x2 v3 | ||
; check: return v4 | ||
} | ||
|
||
function %popcnt_splat_into_splat_popcnt(i64) -> i64x2 { | ||
block0(v0: i64): | ||
v1 = splat.i64x2 v0 | ||
v2 = popcnt.i64x2 v1 | ||
return v2 | ||
; check: v3 = popcnt v0 | ||
; check: v4 = splat.i64x2 v3 | ||
; check: return v4 | ||
} | ||
|
||
function %smin_splat_into_splat_smin(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = smin.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = smin v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %umin_splat_into_splat_umin(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = umin.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = umin v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %smax_splat_into_splat_smax(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = smax.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = smax v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %umax_splat_into_splat_umax(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = splat.i64x2 v1 | ||
v4 = umax.i64x2 v2, v3 | ||
return v4 | ||
; check: v5 = umax v0, v1 | ||
; check: v6 = splat.i64x2 v5 | ||
; check: return v6 | ||
} | ||
|
||
function %rotl_splat_into_splat_rotl(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = rotl.i64x2 v2, v1 | ||
return v3 | ||
; check: v4 = rotl v0, v1 | ||
; check: v5 = splat.i64x2 v4 | ||
; check: return v5 | ||
} | ||
|
||
function %rotr_splat_into_splat_rotr(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = rotr.i64x2 v2, v1 | ||
return v3 | ||
; check: v4 = rotr v0, v1 | ||
; check: v5 = splat.i64x2 v4 | ||
; check: return v5 | ||
} | ||
|
||
function %ishl_splat_into_splat_ishl(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = ishl.i64x2 v2, v1 | ||
return v3 | ||
; check: v4 = ishl v0, v1 | ||
; check: v5 = splat.i64x2 v4 | ||
; check: return v5 | ||
} | ||
|
||
function %ushr_splat_into_splat_ushr(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = ushr.i64x2 v2, v1 | ||
return v3 | ||
; check: v4 = ushr v0, v1 | ||
; check: v5 = splat.i64x2 v4 | ||
; check: return v5 | ||
} | ||
|
||
function %sshr_splat_into_splat_sshr(i64, i64) -> i64x2 { | ||
block0(v0: i64, v1: i64): | ||
v2 = splat.i64x2 v0 | ||
v3 = sshr.i64x2 v2, v1 | ||
return v3 | ||
; check: v4 = sshr v0, v1 | ||
; check: v5 = splat.i64x2 v4 | ||
; check: return v5 | ||
} |