From 1f98223ef3cd0f41668bc7c0114a10bc9851075e Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Fri, 17 Mar 2023 17:04:40 +0000 Subject: [PATCH] cranelift: rewrite urem of constants Note these rules are currently dead, pending resolution of https://github.com/bytecodealliance/wasmtime/issues/5908 --- cranelift/codegen/src/isle_prelude.rs | 5 +++++ cranelift/codegen/src/opts/algebraic.isle | 12 ++++++++++++ cranelift/codegen/src/prelude.isle | 3 +++ .../filetests/filetests/egraph/algebraic.clif | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs index cf0caac323b3..1d512bf386fa 100644 --- a/cranelift/codegen/src/isle_prelude.rs +++ b/cranelift/codegen/src/isle_prelude.rs @@ -441,6 +441,11 @@ macro_rules! isle_common_prelude_methods { } } + #[inline] + fn u64_is_power_of_two(&mut self, x: u64) -> bool { + x.is_power_of_two() + } + #[inline] fn u64_from_bool(&mut self, b: bool) -> u64 { if b { diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle index ce04c271670a..1e4e29674ada 100644 --- a/cranelift/codegen/src/opts/algebraic.isle +++ b/cranelift/codegen/src/opts/algebraic.isle @@ -56,6 +56,7 @@ (subsume zero)) ;; x/1 == x. +;; Currently not active: see issue #5908 (rule (simplify (sdiv ty x (iconst ty (u64_from_imm64 1)))) @@ -65,6 +66,17 @@ (iconst ty (u64_from_imm64 1)))) (subsume x)) +;; x%1 == 0. +;; Currently not active: see issue #5908 +(rule (simplify (urem ty x (iconst ty (u64_from_imm64 1)))) + (subsume (iconst ty (imm64 0)))) + +;; x%c == x&(c-1) when c is a power of 2. +;; Currently not active: see issue #5908 +(rule (simplify (urem ty x (iconst ty (u64_from_imm64 c)))) + (if-let $true (u64_is_power_of_two c)) + (band ty x (iconst ty (imm64 (u64_sub c 1))))) + ;; x>>0 == x<<0 == x rotr 0 == x rotl 0 == x. (rule (simplify (ishl ty x diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle index ef2741570a83..4eb772de5e46 100644 --- a/cranelift/codegen/src/prelude.isle +++ b/cranelift/codegen/src/prelude.isle @@ -181,6 +181,9 @@ (decl pure u64_is_odd (u64) bool) (extern constructor u64_is_odd u64_is_odd) +(decl pure u64_is_power_of_two (u64) bool) +(extern constructor u64_is_power_of_two u64_is_power_of_two) + ;;;; `cranelift_codegen::ir::Type` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (extern const $I8 Type) diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif index 02d38cdd9d36..9547fa4aa3f1 100644 --- a/cranelift/filetests/filetests/egraph/algebraic.clif +++ b/cranelift/filetests/filetests/egraph/algebraic.clif @@ -232,6 +232,24 @@ block0(v0: i32): ; check: return v0 } +function %urem_x_1(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 1 + v2 = urem v0, v1 + return v2 + ; check: v1 = iconst.i32 1 + ; check: v2 = urem v0, v1 +} + +function %urem_x_pow2(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 2 + v2 = urem v0, v1 + return v2 + ; check: v1 = iconst.i32 2 + ; check: v2 = urem v0, v1 +} + function %or_and_y_with_not_y_i8(i8, i8) -> i8 { block0(v0: i8, v1: i8): v2 = band v0, v1