Message ID | 20221024133316.33026-1-aldyh@redhat.com |
---|---|
State | New |
Headers | show |
Series | [PR,tree-optimization/107355] Handle NANs in abs range-op entry. | expand |
Tested on x86-64 Linux. Pushed. On Mon, Oct 24, 2022 at 3:33 PM Aldy Hernandez <aldyh@redhat.com> wrote: > > The problem here is that the threader is coming up with a path where > the only valid result is a NAN. When the abs op1_range entry is > trying to add the negative posibility, it attempts to get the bounds > of the working range. NANs don't have bounds so they need to be > special cased. > > PR tree-optimization/107355 > > gcc/ChangeLog: > > * range-op-float.cc (foperator_abs::op1_range): Handle NAN. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr107355.c: New test. > --- > gcc/range-op-float.cc | 9 +++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr107355.c | 13 +++++++++++++ > 2 files changed, 22 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107355.c > > diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc > index 8777bc70d71..04208c88dd1 100644 > --- a/gcc/range-op-float.cc > +++ b/gcc/range-op-float.cc > @@ -1269,6 +1269,15 @@ foperator_abs::op1_range (frange &r, tree type, > positives.update_nan (/*sign=*/false); > positives.intersect (lhs); > r = positives; > + // Add -NAN if relevant. > + if (r.maybe_isnan ()) > + { > + frange neg_nan; > + neg_nan.set_nan (type, true); > + r.union_ (neg_nan); > + } > + if (r.known_isnan ()) > + return true; > // Then add the negative of each pair: > // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20]. > r.union_ (frange (type, > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c > new file mode 100644 > index 00000000000..40796344bfb > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c > @@ -0,0 +1,13 @@ > +// { dg-do compile } > +// { dg-options "-O2 -fno-guess-branch-probability -fsanitize=float-cast-overflow --param=max-jump-thread-duplication-stmts=240" } > + > +float f; > + > +void > +foo (double d) > +{ > + (char) f; > + long l = __builtin_fabs (d); > + (char) f; > + (long) d; > +} > -- > 2.37.3 >
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 8777bc70d71..04208c88dd1 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -1269,6 +1269,15 @@ foperator_abs::op1_range (frange &r, tree type, positives.update_nan (/*sign=*/false); positives.intersect (lhs); r = positives; + // Add -NAN if relevant. + if (r.maybe_isnan ()) + { + frange neg_nan; + neg_nan.set_nan (type, true); + r.union_ (neg_nan); + } + if (r.known_isnan ()) + return true; // Then add the negative of each pair: // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20]. r.union_ (frange (type, diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c new file mode 100644 index 00000000000..40796344bfb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107355.c @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O2 -fno-guess-branch-probability -fsanitize=float-cast-overflow --param=max-jump-thread-duplication-stmts=240" } + +float f; + +void +foo (double d) +{ + (char) f; + long l = __builtin_fabs (d); + (char) f; + (long) d; +}