https://gcc.gnu.org/g:d0e28326d4254e4824096a7331c8600455c22f73
commit r17-4503-gd0e28326d4254e4824096a7331c8600455c22f73 Author: Naveen <[email protected]> Date: Sun Sep 20 22:06:57 2026 -0700 tree-optimization: Fold redundant integer-float-integer conversions [PR98984] GCC eliminates an integer-to-floating-point-to-integer conversion when the intermediate floating-point type can represent every value of the input integer type. This misses cases where it can represent every value of the final integer type. Extend the existing PR66211 folding pattern to use the final integer precision as an alternative condition when -fno-trapping-math is enabled. Values in range are represented exactly while out-of-range conversions are already undefined or invalid, so removing the intermediate conversion is safe. gcc/ChangeLog: PR tree-optimization/98984 * match.pd: Fold integer-float-integer conversions when the intermediate floating-point significand covers the final integer precision under -fno-trapping-math. gcc/testsuite/ChangeLog: PR tree-optimization/98984 * gcc.dg/tree-ssa/pr98984.c: New test. * gcc.dg/tree-ssa/pr98984-2.c: New test. Signed-off-by: Naveen <[email protected]> Diff: --- gcc/match.pd | 11 +++++---- gcc/testsuite/gcc.dg/tree-ssa/pr98984-2.c | 12 ++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr98984.c | 37 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index e5ffd6b0d991..88533dcf77a8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6210,12 +6210,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* If we are converting an integer to a floating-point that can represent it exactly and back to an integer, we can skip the - floating-point conversion. */ - (if (GIMPLE /* PR66211 */ + floating-point conversion. PR66211, PR98984. */ + (if (GIMPLE && inside_int && inter_float && final_int && ! is_vec - && ((unsigned) significand_size (TYPE_MODE (inter_type)) - >= inside_prec - !inside_unsignedp)) + && (((unsigned) significand_size (TYPE_MODE (inter_type)) + >= inside_prec - !inside_unsignedp) + || (! flag_trapping_math + && ((unsigned) significand_size (TYPE_MODE (inter_type)) + >= final_prec)))) (convert @0))))))) /* (float_type)(integer_type) x -> trunc (x) if the type of x matches diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98984-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98984-2.c new file mode 100644 index 000000000000..caf882d11c1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98984-2.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/98984 */ +/* { dg-do compile { target bitint } } */ +/* { dg-require-effective-target float32 } */ +/* { dg-options "-O2 -std=c23 -fno-trapping-math -fdump-tree-optimized" } */ +/* { dg-add-options float32 } */ + +signed _BitInt(25) +f (long long n) +{ + return (_Float32) n; +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98984.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98984.c new file mode 100644 index 000000000000..51f84c9669b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98984.c @@ -0,0 +1,37 @@ +/* PR tree-optimization/98984 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-trapping-math -fdump-tree-optimized" } */ + + +signed char +f1 (unsigned long long n) +{ + return (float)n; +} + +signed char +f2 (long long n) +{ + return (float)n; +} + +unsigned char +f3 (unsigned int n) +{ + return (float)n; +} + +short +f4 (unsigned long long n) +{ + return (float)n; +} + +unsigned short +f5 (unsigned long long n) +{ + return (double)n; +} + +/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */
