Bug 55152 - MAX_EXPR(a,-a) is really ABS_EXPR(a)
Summary: MAX_EXPR(a,-a) is really ABS_EXPR(a)
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.8.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: missed-optimization
Depends on:
Reported: 2012-10-31 20:16 UTC by Marc Glisse
Modified: 2013-07-14 10:29 UTC (History)
0 users

See Also:
Known to work:
Known to fail:
Last reconfirmed:

fold-const.c patch (1.75 KB, patch)
2013-07-14 10:29 UTC, Marc Glisse
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Marc Glisse 2012-10-31 20:16:45 UTC
I tried compiling this code with -Ofast, but *.optimized still only contained a MAX_EXPR and not an ABS_EXPR (the back-end didn't find the optimization either).

double f(double a){
  return (a>=-a)?a:-a;

It seems that some simple code in fold-const.c could help (fold is called from the front-end for COND_EXPR), not sure if anything would call it if -a went though a temporary variable though.
Comment 1 Andrew Pinski 2012-10-31 20:18:58 UTC
Only if you ignore signed zeros and maybe even NaNs.
Comment 2 Marc Glisse 2012-10-31 21:14:12 UTC
Ignoring signed zeros, sure, that's also required to generate a MAX_EXPR in the first place. NaNs, I don't know, it sounds to me like they have an effect on generating a MAX_EXPR, but turning the MAX into an ABS should be safe.

(sometimes I wish for a __builtin_max, and -fno-nans)
Comment 3 Marc Glisse 2012-10-31 21:27:27 UTC
Actually, looking at the doc of MAX_EXPR in tree.def (nothing in generic.texi), we don't even need to ignore signed zeros to turn MAX_EXPR into ABS_EXPR:

/* Minimum and maximum values.  When used with floating point, if both
   operands are zeros, or if either operand is NaN, then it is unspecified
   which of the two operands is returned as the result.  */
Comment 4 Marc Glisse 2013-07-14 10:29:19 UTC
Created attachment 30502 [details]
fold-const.c patch

I've had this patch on my hard drive for a while and it will be better here. It needs more work. The MAX optimization can probably never be reached from C code (and the signed overflow warning seems unnecessary in this particular case), part of the patch should move to gimple I guess, and I shouldn't produce the non-canonical 0 op X when I could easily use swap_tree_comparison.