From dae8b9e2bbb6017bf90d68c7b720c500125c8295 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sat, 3 Sep 2022 15:41:06 +0200 Subject: [PR/middle-end 106819] NANs can never be a singleton Possible NANs can never be a singleton, so they will never be propagated. This was the intent, and then the signed zero code crept in, and was mistakenly checked before the NAN. PR/middle-end 106819 gcc/ChangeLog: * value-range.cc (frange::singleton_p): Move NAN check to the top. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr106819.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr106819.c | 24 ++++++++++++++++++++++++ gcc/value-range.cc | 9 ++++----- 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr106819.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr106819.c b/gcc/testsuite/gcc.dg/tree-ssa/pr106819.c new file mode 100644 index 0000000..1272d4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr106819.c @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-evrp-details" } + +static int isNaN(double x) +{ + return x != x; +} + +static double opCmpProper(int lhs, double rhs) +{ + return lhs < rhs ? -1.0 + : lhs > rhs ? 1.0 + : lhs == rhs ? 0.0 + : __builtin_nan(""); +} + +int main() +{ + if (!isNaN(opCmpProper(41, __builtin_nan("")))) + __builtin_abort(); + return 0; +} + +// { dg-final {scan-tree-dump-not "Folds to: 0.0" "evrp" } } diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 6fd6e3b..a1c29f7 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -632,6 +632,10 @@ frange::singleton_p (tree *result) const { if (m_kind == VR_RANGE && real_identical (&m_min, &m_max)) { + // Return false for any singleton that may be a NAN. + if (HONOR_NANS (m_type) && !get_nan ().no_p ()) + return false; + // Return the appropriate zero if known. if (HONOR_SIGNED_ZEROS (m_type) && zero_p ()) { @@ -649,11 +653,6 @@ frange::singleton_p (tree *result) const } return false; } - - // Return false for any singleton that may be a NAN. - if (HONOR_NANS (m_type) && !get_nan ().no_p ()) - return false; - if (result) *result = build_real (m_type, m_min); return true; -- cgit v1.1