From da93f647974518e111561b3b451ef8c4a576bf20 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Dec 2024 17:06:50 -0700 Subject: [PATCH] pulley: Fill out lowerings for `{s,u}{min,max}` (#9819) Gets another `*.wast` test passing cc #9783 --- .../codegen/src/isa/pulley_shared/lower.isle | 20 +++++++ crates/wast-util/src/lib.rs | 1 - pulley/src/interp.rs | 56 +++++++++++++++++++ pulley/src/lib.rs | 17 ++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/cranelift/codegen/src/isa/pulley_shared/lower.isle b/cranelift/codegen/src/isa/pulley_shared/lower.isle index 57ff450fafc6..e1df6602706b 100644 --- a/cranelift/codegen/src/isa/pulley_shared/lower.isle +++ b/cranelift/codegen/src/isa/pulley_shared/lower.isle @@ -240,6 +240,26 @@ (rule 1 (lower (has_type $I64 (bnot a))) (pulley_xbnot64 a)) +;;;; Rules for `umin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $I32 (umin a b))) (pulley_xmin32_u a b)) +(rule (lower (has_type $I64 (umin a b))) (pulley_xmin64_u a b)) + +;;;; Rules for `smin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $I32 (smin a b))) (pulley_xmin32_s a b)) +(rule (lower (has_type $I64 (smin a b))) (pulley_xmin64_s a b)) + +;;;; Rules for `umax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $I32 (umax a b))) (pulley_xmax32_u a b)) +(rule (lower (has_type $I64 (umax a b))) (pulley_xmax64_u a b)) + +;;;; Rules for `smax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(rule (lower (has_type $I32 (smax a b))) (pulley_xmax32_s a b)) +(rule (lower (has_type $I64 (smax a b))) (pulley_xmax64_s a b)) + ;;;; Rules for `ctz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type $I32 (ctz a))) (pulley_xctz32 a)) diff --git a/crates/wast-util/src/lib.rs b/crates/wast-util/src/lib.rs index 321154f92fd9..00551c46f29e 100644 --- a/crates/wast-util/src/lib.rs +++ b/crates/wast-util/src/lib.rs @@ -400,7 +400,6 @@ impl WastTest { "misc_testsuite/memory-combos.wast", "misc_testsuite/memory64/simd.wast", "misc_testsuite/memory64/threads.wast", - "misc_testsuite/rust_fannkuch.wast", "misc_testsuite/simd/almost-extmul.wast", "misc_testsuite/simd/canonicalize-nan.wast", "misc_testsuite/simd/cvt-from-uint.wast", diff --git a/pulley/src/interp.rs b/pulley/src/interp.rs index f281933264a5..4800015ddfc2 100644 --- a/pulley/src/interp.rs +++ b/pulley/src/interp.rs @@ -1814,6 +1814,62 @@ impl OpVisitor for Interpreter<'_> { ControlFlow::Continue(()) } + fn xmin32_u(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_u32(); + let b = self.state[operands.src2].get_u32(); + self.state[operands.dst].set_u32(a.min(b)); + ControlFlow::Continue(()) + } + + fn xmin32_s(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_i32(); + let b = self.state[operands.src2].get_i32(); + self.state[operands.dst].set_i32(a.min(b)); + ControlFlow::Continue(()) + } + + fn xmax32_u(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_u32(); + let b = self.state[operands.src2].get_u32(); + self.state[operands.dst].set_u32(a.max(b)); + ControlFlow::Continue(()) + } + + fn xmax32_s(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_i32(); + let b = self.state[operands.src2].get_i32(); + self.state[operands.dst].set_i32(a.max(b)); + ControlFlow::Continue(()) + } + + fn xmin64_u(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_u64(); + let b = self.state[operands.src2].get_u64(); + self.state[operands.dst].set_u64(a.min(b)); + ControlFlow::Continue(()) + } + + fn xmin64_s(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_i64(); + let b = self.state[operands.src2].get_i64(); + self.state[operands.dst].set_i64(a.min(b)); + ControlFlow::Continue(()) + } + + fn xmax64_u(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_u64(); + let b = self.state[operands.src2].get_u64(); + self.state[operands.dst].set_u64(a.max(b)); + ControlFlow::Continue(()) + } + + fn xmax64_s(&mut self, operands: BinaryOperands) -> ControlFlow { + let a = self.state[operands.src1].get_i64(); + let b = self.state[operands.src2].get_i64(); + self.state[operands.dst].set_i64(a.max(b)); + ControlFlow::Continue(()) + } + fn fconst32(&mut self, dst: FReg, bits: u32) -> ControlFlow { self.state[dst].set_f32(f32::from_bits(bits)); ControlFlow::Continue(()) diff --git a/pulley/src/lib.rs b/pulley/src/lib.rs index 69b50176743d..bb8b83f7994a 100644 --- a/pulley/src/lib.rs +++ b/pulley/src/lib.rs @@ -401,6 +401,23 @@ macro_rules! for_each_op { /// `dst = !src1` xbnot64 = XBnot64 { dst: XReg, src: XReg }; + /// `low32(dst) = min(low32(src1), low32(src2))` (unsigned) + xmin32_u = Xmin32U { operands: BinaryOperands }; + /// `low32(dst) = min(low32(src1), low32(src2))` (signed) + xmin32_s = Xmin32S { operands: BinaryOperands }; + /// `low32(dst) = max(low32(src1), low32(src2))` (unsigned) + xmax32_u = Xmax32U { operands: BinaryOperands }; + /// `low32(dst) = max(low32(src1), low32(src2))` (signed) + xmax32_s = Xmax32S { operands: BinaryOperands }; + /// `dst = min(src1, src2)` (unsigned) + xmin64_u = Xmin64U { operands: BinaryOperands }; + /// `dst = min(src1, src2)` (signed) + xmin64_s = Xmin64S { operands: BinaryOperands }; + /// `dst = max(src1, src2)` (unsigned) + xmax64_u = Xmax64U { operands: BinaryOperands }; + /// `dst = max(src1, src2)` (signed) + xmax64_s = Xmax64S { operands: BinaryOperands }; + /// `low32(dst) = bits` fconst32 = FConst32 { dst: FReg, bits: u32 }; /// `dst = bits`