https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91425

--- Comment #15 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #14)
> (In reply to Drea Pinski from comment #12)
> > I have to think about the full fix.
> > 
> > == returns false for nans.
> > 
> > U> returns false for nan. Unlike >.
> > 
> > So if we have a || b where a was !(u) if b is trapping then this would be
> > true also for nans. If a was !(t) then this would turn into u which was
> > false but then b being trapping would would be ok too. As long as we get
> > trapping back, I think it would not.
> > 
> > 
> > So for signaling nans, the we should not allow the conversion.
> > 
> > For a&&b, if a was !(t) than that turns into u .  We need to get a trapping
> > version back but I am not positive it would.
> 
> U> only has meaning for integers.  NaN is not an integer.

Note `u>` is UNGT_EXPR in this context rather than unsigned Greater than.

That is:
/* These are equivalent to unordered or ...  */
DEFTREECODE (UNLT_EXPR, "unlt_expr", tcc_comparison, 2)
DEFTREECODE (UNLE_EXPR, "unle_expr", tcc_comparison, 2)
DEFTREECODE (UNGT_EXPR, "ungt_expr", tcc_comparison, 2)
DEFTREECODE (UNGE_EXPR, "unge_expr", tcc_comparison, 2)
DEFTREECODE (UNEQ_EXPR, "uneq_expr", tcc_comparison, 2)

Which is printed out in the gimple dumps as `u>`.
>From op_symbol_code:

    case UNGT_EXPR:
      return (flags & TDF_GIMPLE) ? "__UNGT" : "u>";


the `unordered or ...` tree codes don't trap while the `...` ones do.

I know RTL has LTU but that is different from the tree codes.
The RTL equivant to those tree codes are:

/* These are equivalent to unordered or ...  */
DEF_RTL_EXPR(UNEQ, "uneq", "ee", RTX_COMM_COMPARE)
DEF_RTL_EXPR(UNGE, "unge", "ee", RTX_COMPARE)
DEF_RTL_EXPR(UNGT, "ungt", "ee", RTX_COMPARE)
DEF_RTL_EXPR(UNLE, "unle", "ee", RTX_COMPARE)
DEF_RTL_EXPR(UNLT, "unlt", "ee", RTX_COMPARE)


So going back to the problem here. we have:
`!(a_3(D) u>= b_4(D)) || a_3(D) < b_4(D)`

So a NAN here would be false for the first part and then would trap for the
second part.

So `!(u0) || t1` can be done as `t0 | t1` just fine where t0 is the inversion
of u0 (ignorning trapping) and still get the same trapping behavior.


As far as && case goes we can have:
`!(t0) && t1` can be convert into `u0 && t1` I think as that result will trap
still.

`!(u0) && t1` cannot be handled as NaN will break the trapping as it will short
circuit.
Same for `!(t0) || t1`.

So the patch in comment #13 is wrong, because it does not check if we have
`unordered or` comparison when it comes to inversion.

Reply via email to