Hi Mike,
Irrespective of whether -Ofast is used or not, should’nt we generate XSCMPUDP 
instruction for ‘isgreater()’ operation? This is because XSCMPGTDP insn will 
generate a trap if either operand is an SNaN or a QNaN. Whereas, XSCMPUDP insn 
will generate a trap only if either operand is an SNaN. The issue with the 
failing glibc tests is that an “Invalid operation” exception is being thrown 
due to qNaNs.

Regards,
Surya

On 09/05/25 5:14 am, Michael Meissner wrote:
> This has been posted previously.  This patch includes fixing some typos that
> Bernhard Reutner-Fischer suggested.
> 
> In bug PR target/118541 on power9, power10, and power11 systems, for the
> function:
> 
>         extern double __ieee754_acos (double);
> 
>         double
>         __acospi (double x)
>         {
>           double ret = __ieee754_acos (x) / 3.14;
>           return __builtin_isgreater (ret, 1.0) ? 1.0 : ret;
>         }
> 
> GCC currently generates the following code:
> 
>         Power9                          Power10 and Power11
>         ======                          ===================
>         bl __ieee754_acos               bl __ieee754_acos@notoc
>         nop                             plfd 0,.LC0@pcrel
>         addis 9,2,.LC2@toc@ha           xxspltidp 12,1065353216
>         addi 1,1,32                     addi 1,1,32
>         lfd 0,.LC2@toc@l(9)             ld 0,16(1)
>         addis 9,2,.LC0@toc@ha           fdiv 0,1,0
>         ld 0,16(1)                      mtlr 0
>         lfd 12,.LC0@toc@l(9)            xscmpgtdp 1,0,12
>         fdiv 0,1,0                      xxsel 1,0,12,1
>         mtlr 0                          blr
>         xscmpgtdp 1,0,12
>         xxsel 1,0,12,1
>         blr
> 
> This is because ifcvt.c optimizes the conditional floating point move to use 
> the
> XSCMPGTDP instruction.
> 
> However, the XSCMPGTDP instruction will generate an interrupt if one of the
> arguments is a signalling NaN and signalling NaNs can generate an interrupt.
> The IEEE comparison functions (isgreater, etc.) require that the comparison 
> not
> raise an interrupt.
> 
> The following patch changes the PowerPC back end so that ifcvt.c will not 
> change
> the if/then test and move into a conditional move if the comparison is one of
> the comparisons that do not raise an error with signalling NaNs and -Ofast is
> not used.  If a normal comparison is used or -Ofast is used, GCC will continue
> to generate XSCMPGTDP and XXSEL.
> 
> For the following code:
> 
>         double
>         ordered_compare (double a, double b, double c, double d)
>         {
>           return __builtin_isgreater (a, b) ? c : d;
>         }
> 
>         /* Verify normal > does generate xscmpgtdp.  */
> 
>         double
>         normal_compare (double a, double b, double c, double d)
>         {
>           return a > b ? c : d;
>         }
> 
> with the following patch, GCC generates the following for power9, power10, and
> power11:
> 
>         ordered_compare:
>                 fcmpu 0,1,2
>                 fmr 1,4
>                 bnglr 0
>                 fmr 1,3
>                 blr
> 
>         normal_compare:
>                 xscmpgtdp 1,1,2
>                 xxsel 1,4,3,1
>                 blr
> 
> I have built bootstrap compilers on big endian power9 systems and little 
> endian
> power9/power10 systems and there were no regressions.  Can I check this patch
> into the GCC trunk, and after a waiting period, can I check this into the 
> active
> older branches?

Reply via email to