diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle index 16ae97040a..ce04c27167 100644 --- a/cranelift/codegen/src/opts/algebraic.isle +++ b/cranelift/codegen/src/opts/algebraic.isle @@ -527,6 +527,9 @@ ;; with the `bitselect` instruction, but the pattern is a bit more complicated ;; due to most bitselects-over-floats having bitcasts. +;; fneg(fneg(x)) == x. +(rule (simplify (fneg ty (fneg ty x))) (subsume x)) + ;; 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)) diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif index 5520f0a4db..02d38cdd9d 100644 --- a/cranelift/filetests/filetests/egraph/algebraic.clif +++ b/cranelift/filetests/filetests/egraph/algebraic.clif @@ -492,6 +492,15 @@ block0(v1: i16): ; check: v4 = sextend.i64 v1 ; check: return v4 +function %double_fneg(f32) -> f32 { +block0(v1: f32): + v2 = fneg v1 + v3 = fneg v2 + return v3 +} + +; check: return v1 + function %fma_double_fneg(f32, f32, f32) -> f32 { block0(v1: f32, v2: f32, v3: f32): v4 = fneg v1