From 3ff3994a128e900dfe7a465c7f36fc5a074d07ef Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 2 Mar 2023 12:28:32 -0600 Subject: [PATCH] Add egraph optimization for fneg's cancelling out (#5910) This implements comments from #5895 to cancel out `fneg` operations in `fma` instructions. Additional support for `fmul` is added as well. --- cranelift/codegen/src/opts/algebraic.isle | 10 +++++++++ .../filetests/filetests/egraph/algebraic.clif | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle index ecd71988ce..eac1650654 100644 --- a/cranelift/codegen/src/opts/algebraic.isle +++ b/cranelift/codegen/src/opts/algebraic.isle @@ -527,3 +527,13 @@ (rule (simplify (vselect ty (fcmp _ (FloatCC.GreaterThan) x y) x y)) (fmax_pseudo ty x y)) + +;; If both of the multiplied arguments to an `fma` are negated then remove +;; both of them since they cancel out. +(rule (simplify (fma ty (fneg ty x) (fneg ty y) z)) + (fma ty x y z)) + +;; If both of the multiplied arguments to an `fmul` are negated then remove +;; both of them since they cancel out. +(rule (simplify (fmul ty (fneg ty x) (fneg ty y))) + (fmul ty x y)) diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif index 24460845a9..573135d3b0 100644 --- a/cranelift/filetests/filetests/egraph/algebraic.clif +++ b/cranelift/filetests/filetests/egraph/algebraic.clif @@ -483,3 +483,25 @@ block0(v1: i16): ; check: v4 = sextend.i64 v1 ; check: return v4 + +function %fma_double_fneg(f32, f32, f32) -> f32 { +block0(v1: f32, v2: f32, v3: f32): + v4 = fneg v1 + v5 = fneg v2 + v6 = fma v4, v5, v3 + return v6 +} + +; check: v7 = fma v1, v2, v3 +; check: return v7 + +function %fmul_double_fneg(f32, f32) -> f32 { +block0(v1: f32, v2: f32): + v3 = fneg v1 + v4 = fneg v2 + v5 = fmul v3, v4 + return v5 +} + +; check: v6 = fmul v1, v2 +; check: return v6