https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116463
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- I think a - ((b * -c) + (d * -e)) -> a + (b * c) + (d * e) is a good simplification to be made, but it's difficult to do this with canonicalization only. Like a * -b -> -(a * b) as the negate might combine with both other negates down and upstream. But for a*-b + c * -d it might be more obvious to turn that into -a*b - c*d. Maybe reassoc can be of help here - IIRC it turns b * -c into b * c * -1, undistribute_ops_list might get that. Note one issue is that complex lowering leaves around dead stmts, confusing reassoc and forwprop, in particular - _10 = COMPLEX_EXPR <_18, _6>; stay around until reassoc. scheduling dce for testing shows reassoc does something. It's update_complex_assignment who replaces existing complex stmts with COMPLEX_EXPRs, we should possibly resort do simple_dce_from_worklist to clean those. Let me try to do that.