https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84841
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 43670 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43670&action=edit gcc8-pr84841.patch Untested fix. The problem actually aren't the multiple REAL_CSTs, but the artificial -1.0 added by try_special_add_to_ops which isn't reflected in the original IL. We rely on that one to be merged with other constants. And, const_binop generally fails only for inexact computations, multiplication by -1.0 or 1.0 should never be inexact. So this patch just makes sure we sort -1.0 (and 1.0 which has similar properties) last. Another possibility would be to try harder if some const_binop fails, up to O(n^2) attempts where n is the number of REAL_CSTs at the end of the ops list. Even with -frounding-math or the IBM long double, we can be successful with some foldings and not others. Is that worth it though? And, seems the sorting wasn't matching the comment: /* We want integer ones to end up last no matter what, since they are the ones we can do the most with. */ I must say I fail to see when we'd have constants of different types in the same ops list, but the documentation says sort integers (i.e. the highest constant_type values) last, but sorting function did the opposite.