Hello, This patch introduces an optimization for narrowing binary and builtin math operations to the smallest type when unsafe math optimizations are enabled (typically -Ofast or -ffast-math). Consider the example: float f (float x) { return 1.0 / sqrt (x); } f: fcvt d0, s0 fmov d1, 1.0e+0 fsqrt d0, d0 fdiv d0, d1, d0 fcvt s0, d0 ret Given that all outputs are of float type, we can do the whole calculation in single precision and avoid any potentially expensive conversions between single and double precision. Aka the expression would end up looking more like float f (float x) { return 1.0f / sqrtf (x); } f: fsqrt s0, s0 fmov s1, 1.0e+0 fdiv s0, s1, s0 ret This optimization will narrow casts around math builtins, and also not try to find the widest type for calculations when processing binary math operations (if unsafe math optimizations are enable). Added tests to verify that narrower math builtins are chosen and no unnecessary casts are introduced when appropriate. Bootstrapped and regtested on aarch64 and x86_64 with no regressions. I don't have write access, so if OK for trunk then can someone commit on my behalf? Regards, Barney gcc/ChangeLog: 2019-09-02 Barnaby Wilks * builtins.c (mathfn_built_in): Expose find implicit builtin parameter. * builtins.h (mathfn_built_in): Likewise. * match.pd: Add expressions for simplifying builtin and binary math expressions. gcc/testsuite/ChangeLog: 2019-09-02 Barnaby Wilks * gcc.dg/fold-single-precision.c: New test.