phiopt: Improve spaceship_replacement for HONOR_NANS [PR117612]
The following patch optimizes spaceship followed by comparisons of the spaceship value even for floating point spaceship when NaNs can appear. operator<=> for this emits roughly signed char c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; and I believe the /* The optimization may be unsafe due to NaNs. */ comment just isn't true. Sure, the i == j comparison doesn't raise exceptions on qNaNs, but if one of the operands is qNaN, then i == j is false and i < j or i > j is then executed and raises exceptions even on qNaNs. And we can safely optimize say c == -1 comparison after the above into i < j, that also raises exceptions like before and handles NaNs the same way as the original. The only unsafe transormation would be c == 0 or c != 0, turning it into i == j or i != j wouldn't raise exception, so I'm not doing that optimization (but other parts of the compiler optimize the i < j comparison away anyway). Anyway, to match the HONOR_NANS case, we need to verify that the second comparison has true edge to the phi_bb (yielding there -1 or 1), it can't be the false edge because when NaNs are honored, the false edge is for both the case where the inverted comparison is true or when one of the operands is NaN. Similarly we need to ensure that the two non-equality comparisons are the opposite, while for -ffast-math we can in some cases get one comparison x >= 5.0 and the other x > 5.0 and it is fine, because NaN is UB, when NaNs are honored, they must be different to leave the unordered case with 2 value as the last one remaining. The patch also punts if HONOR_NANS and the phi has just 3 arguments instead of 4. When NaNs are honored, we also in some cases need to perform some comparison and then invert its result (so that exceptions are properly thrown and we get the correct result). 2024-11-21 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94589 PR tree-optimization/117612 * tree-ssa-phiopt.cc (spaceship_replacement): Handle HONOR_NANS (TREE_TYPE (lhs1)) case when possible. * gcc.dg/pr94589-5.c: New test. * gcc.dg/pr94589-6.c: New test. * g++.dg/opt/pr94589-5.C: New test. * g++.dg/opt/pr94589-6.C: New test.
Showing
- gcc/testsuite/g++.dg/opt/pr94589-5.C 26 additions, 0 deletionsgcc/testsuite/g++.dg/opt/pr94589-5.C
- gcc/testsuite/g++.dg/opt/pr94589-6.C 138 additions, 0 deletionsgcc/testsuite/g++.dg/opt/pr94589-6.C
- gcc/testsuite/gcc.dg/pr94589-5.c 35 additions, 0 deletionsgcc/testsuite/gcc.dg/pr94589-5.c
- gcc/testsuite/gcc.dg/pr94589-6.c 146 additions, 0 deletionsgcc/testsuite/gcc.dg/pr94589-6.c
- gcc/tree-ssa-phiopt.cc 87 additions, 26 deletionsgcc/tree-ssa-phiopt.cc
Loading
Please register or sign in to comment