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