Jiufu Guo <guoji...@linux.ibm.com> writes:

Backported to GCC 9, preapproved by Segher.

Thanks,

Jiufu

> Segher Boessenkool <seg...@kernel.crashing.org> writes:
>
>> Hi!
>>
>> On Thu, Mar 05, 2020 at 10:46:58AM +0800, Jiufu Guo wrote:
>>> PR93709 mentioned regressions on maxlocval_4.f90 and minlocval_f.f90 which
>>> relates to max of '-inf' and 'nan'. This regression occur on P9 which has
>>> new instruction 'xsmaxcdp/xsmincdp'.
>>> The similar issue also could be find on `a < b ? b : a` which is also
>>> generated as `xsmaxcdp` under -O2 for P9. This instruction `xsmaxcdp`
>>> more like C/C++ semantic (a>b?a:b). A testcase is added for this issue.
>>> 
>>> The following patch improve code to check -+0 and NaN before 'smax/smin' to
>>> be generated for those cases.
>>
>>> -  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0, false_cond))
>>> +  /* Only when -fno-signed-zeros and -ffinite_math_only are in effect,
>>> +     `op0 < op1 ? op1 : op0` works like `op1 > op0 ? op1 : op0` which 
>>> +     could use smax;
>>> +     `op0 > op1 ? op1 : op0` works like `op1 < op0 ? op1 : op0` which
>>> +     could use smin.  */
>>> +  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0, false_cond)
>>> +      && (flag_finite_math_only && !flag_signed_zeros))
>>>      max_p = !max_p;
>>
>> I know I asked for it, but should this use HONOR_NANS (compare_mode)
>> instead?  Infinities will work fine?  Just NaNs and zeros won't.
> HONOR_NANS(mode) is `MODE_HAS_NANS (mode) && !flag_finite_math_only`.
> We know the mode is SF or DF.  Both maybe ok for current code.
>
> I agree with you HONOR_NANS would be better, it is more generic for
> front-end, gimple and rtl.  And rs6000_emit_p9_fp_minmax maybe called
> without checking mode in future code, in this case HONOR_NANS is
> better.
>
> I updated the code as:
> ```
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index f34e1ba70c6..b057f689b56 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -14836,7 +14836,11 @@ rs6000_emit_p9_fp_minmax (rtx dest, rtx op, rtx
> true_cond, rtx false_cond)
>    if (rtx_equal_p (op0, true_cond) && rtx_equal_p (op1, false_cond))
>         ;
>
> -  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0,
>    false_cond))
>    +  /* Only when NaNs and signed-zeros are not in effect, smax could be
>    +     used for `op0 < op1 ? op1 : op0`, and smin could be used for
>    +     `op0 > op1 ? op1 : op0`.  */
>    +  else if (rtx_equal_p (op1, true_cond) && rtx_equal_p (op0, false_cond)
>    +          && !HONOR_NANS (compare_mode) &&
>    !HONOR_SIGNED_ZEROS(compare_mode))
>         max_p = !max_p;
>
>    else
> ```
> This code works fine. I'm going to submit it.
>
> Thanks!
> Jiufu Guo
>
>>
>> Okay for trunk with that change (if it works :-) )  Thanks!
>>
>>
>> Segher

Reply via email to