diff --git a/cranelift/codegen/src/preopt.peepmatic b/cranelift/codegen/src/preopt.peepmatic index 604460dd57..cd988ff7d9 100644 --- a/cranelift/codegen/src/preopt.peepmatic +++ b/cranelift/codegen/src/preopt.peepmatic @@ -191,3 +191,9 @@ (=> (when (udiv_imm $C $x) (is-power-of-two $C)) (ushr_imm $(log2 $C) $x)) + +;; Remainder by a power of two -> bitwise and with decreased by one constant. +(=> (when (urem_imm $C $x) + (is-power-of-two $C) + (fits-in-native-word $C)) + (band_imm $(isub $C 1) $x)) diff --git a/cranelift/codegen/src/preopt.serialized b/cranelift/codegen/src/preopt.serialized index bae915dab0..1bb11b24ad 100644 Binary files a/cranelift/codegen/src/preopt.serialized and b/cranelift/codegen/src/preopt.serialized differ diff --git a/cranelift/peepmatic/crates/runtime/src/operator.rs b/cranelift/peepmatic/crates/runtime/src/operator.rs index c8f06b8514..2915f36290 100644 --- a/cranelift/peepmatic/crates/runtime/src/operator.rs +++ b/cranelift/peepmatic/crates/runtime/src/operator.rs @@ -237,6 +237,10 @@ pub enum UnquoteOperator { #[peepmatic(params(iNN, iNN), result(iNN))] Imul, + /// Compile-time `isub` of two constant values. + #[peepmatic(params(iNN, iNN), result(iNN))] + Isub, + /// Take the base-2 log of a power of two integer. #[peepmatic(params(iNN), result(iNN))] Log2, diff --git a/cranelift/peepmatic/crates/runtime/src/optimizer.rs b/cranelift/peepmatic/crates/runtime/src/optimizer.rs index 589c3f7761..f477db85ac 100644 --- a/cranelift/peepmatic/crates/runtime/src/optimizer.rs +++ b/cranelift/peepmatic/crates/runtime/src/optimizer.rs @@ -77,7 +77,8 @@ where | UnquoteOperator::Bor | UnquoteOperator::Bxor | UnquoteOperator::Iadd - | UnquoteOperator::Imul => unreachable!("not a unary unquote operator: {:?}", operator), + | UnquoteOperator::Imul + | UnquoteOperator::Isub => unreachable!("not a unary unquote operator: {:?}", operator), } } @@ -99,6 +100,7 @@ where UnquoteOperator::Bxor => fold_ints!(a, b, |x, y| x ^ y), UnquoteOperator::Iadd => fold_ints!(a, b, |x, y| x.wrapping_add(y)), UnquoteOperator::Imul => fold_ints!(a, b, |x, y| x.wrapping_mul(y)), + UnquoteOperator::Isub => fold_ints!(a, b, |x, y| x.wrapping_sub(y)), UnquoteOperator::Log2 | UnquoteOperator::Neg => { unreachable!("not a binary unquote operator: {:?}", operator) }