https://gcc.gnu.org/g:4ddc6326f4ab0ae721d3b525a2e53a5331c64785

commit 4ddc6326f4ab0ae721d3b525a2e53a5331c64785
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Thu Aug 14 17:16:21 2025 -0400

    Fix PR 118541, do not generate floating point cmoves for IEEE compares.
    
    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.cc 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.
    
    This patch just eliminates the generation of XSCMPEQDP, XSCMPEQQP, 
XSCMPGTDP,
    XSCMPGTQP, XSCMPGEDP, and XSCMPGEQP instructions.
    
    2025-08-14  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            PR target/118541
            * config/rs6000/predicates.md (fpmask_comparison_operator): Delete
            predicate.
            (invert_fpmask_comparison_operator): Likewise.
            * config/rs6000/rs6000.md (mov<SFDF:mode><SFDF2:mode>cc_p9): Delete
            insn.
            (fpmask<mode>, SFDF iterator): Likewise.
            (xxsel<mode>): Likewise.
            (mov<mode>cc): Likewise.
            (mov<mode>cc_p10): Likewise.
            (mov<mode>cc_invert_p10): Likewise.
            (fpmask<mode>, IEEE128 iterator): Likewise.

Diff:
---
 gcc/config/rs6000/predicates.md |  11 ---
 gcc/config/rs6000/rs6000.md     | 197 ----------------------------------------
 2 files changed, 208 deletions(-)

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 647e89afb6a7..065cdb10e10f 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1458,17 +1458,6 @@
   (and (match_operand 0 "branch_comparison_operator")
        (match_code "ne,le,ge,leu,geu,ordered")))
 
-;; Return 1 if OP is a comparison operator suitable for floating point
-;; vector/scalar comparisons that generate a -1/0 mask.
-(define_predicate "fpmask_comparison_operator"
-  (match_code "eq,gt,ge"))
-
-;; Return 1 if OP is a comparison operator suitable for vector/scalar
-;; comparisons that generate a 0/-1 mask (i.e. the inverse of
-;; fpmask_comparison_operator).
-(define_predicate "invert_fpmask_comparison_operator"
-  (match_code "ne,unlt,unle"))
-
 ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar
 ;; comparisons that generate a -1/0 mask.
 (define_predicate "vecint_comparison_operator"
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4b0467ba1b80..aa0b49d6e080 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5747,203 +5747,6 @@
   "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
   "fsel %0,%1,%2,%3"
   [(set_attr "type" "fp")])
-
-(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
-  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
-       (if_then_else:SFDF
-        (match_operator:CCFP 1 "fpmask_comparison_operator"
-               [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
-                (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
-        (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
-        (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
-   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
-  "TARGET_P9_MINMAX"
-  "#"
-  "&& 1"
-  [(set (match_dup 6)
-       (if_then_else:V2DI (match_dup 1)
-                          (match_dup 7)
-                          (match_dup 8)))
-   (set (match_dup 0)
-       (if_then_else:SFDF (ne (match_dup 6)
-                              (match_dup 8))
-                          (match_dup 4)
-                          (match_dup 5)))]
-{
-  if (GET_CODE (operands[6]) == SCRATCH)
-    operands[6] = gen_reg_rtx (V2DImode);
-
-  operands[7] = CONSTM1_RTX (V2DImode);
-  operands[8] = CONST0_RTX (V2DImode);
-}
- [(set_attr "length" "8")
-  (set_attr "type" "vecperm")])
-
-;; Handle inverting the fpmask comparisons.
-(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
-  [(set (match_operand:SFDF 0 "vsx_register_operand" "=&wa,wa")
-       (if_then_else:SFDF
-        (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
-               [(match_operand:SFDF2 2 "vsx_register_operand" "wa,wa")
-                (match_operand:SFDF2 3 "vsx_register_operand" "wa,wa")])
-        (match_operand:SFDF 4 "vsx_register_operand" "wa,wa")
-        (match_operand:SFDF 5 "vsx_register_operand" "wa,wa")))
-   (clobber (match_scratch:V2DI 6 "=0,&wa"))]
-  "TARGET_P9_MINMAX"
-  "#"
-  "&& 1"
-  [(set (match_dup 6)
-       (if_then_else:V2DI (match_dup 9)
-                          (match_dup 7)
-                          (match_dup 8)))
-   (set (match_dup 0)
-       (if_then_else:SFDF (ne (match_dup 6)
-                              (match_dup 8))
-                          (match_dup 5)
-                          (match_dup 4)))]
-{
-  rtx op1 = operands[1];
-  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
-
-  if (GET_CODE (operands[6]) == SCRATCH)
-    operands[6] = gen_reg_rtx (V2DImode);
-
-  operands[7] = CONSTM1_RTX (V2DImode);
-  operands[8] = CONST0_RTX (V2DImode);
-
-  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
-}
- [(set_attr "length" "8")
-  (set_attr "type" "vecperm")])
-
-(define_insn "*fpmask<mode>"
-  [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
-       (if_then_else:V2DI
-        (match_operator:CCFP 1 "fpmask_comparison_operator"
-               [(match_operand:SFDF 2 "vsx_register_operand" "wa")
-                (match_operand:SFDF 3 "vsx_register_operand" "wa")])
-        (match_operand:V2DI 4 "all_ones_constant" "")
-        (match_operand:V2DI 5 "zero_constant" "")))]
-  "TARGET_P9_MINMAX"
-  "xscmp%V1dp %x0,%x2,%x3"
-  [(set_attr "type" "fpcompare")])
-
-(define_insn "*xxsel<mode>"
-  [(set (match_operand:SFDF 0 "vsx_register_operand" "=wa")
-       (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" 
"wa")
-                              (match_operand:V2DI 2 "zero_constant" ""))
-                          (match_operand:SFDF 3 "vsx_register_operand" "wa")
-                          (match_operand:SFDF 4 "vsx_register_operand" "wa")))]
-  "TARGET_P9_MINMAX"
-  "xxsel %x0,%x4,%x3,%x1"
-  [(set_attr "type" "vecmove")])
-
-;; Support for ISA 3.1 IEEE 128-bit conditional move.  The mode used in the
-;; comparison must be the same as used in the move.
-(define_expand "mov<mode>cc"
-   [(set (match_operand:IEEE128 0 "gpc_reg_operand")
-        (if_then_else:IEEE128 (match_operand 1 "comparison_operator")
-                              (match_operand:IEEE128 2 "gpc_reg_operand")
-                              (match_operand:IEEE128 3 "gpc_reg_operand")))]
-  "TARGET_POWER10 && TARGET_FLOAT128_HW"
-{
-  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
-    DONE;
-  else
-    FAIL;
-})
-
-(define_insn_and_split "*mov<mode>cc_p10"
-  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
-       (if_then_else:IEEE128
-        (match_operator:CCFP 1 "fpmask_comparison_operator"
-               [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
-                (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
-        (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
-        (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
-   (clobber (match_scratch:V2DI 6 "=0,&v"))]
-  "TARGET_POWER10 && TARGET_FLOAT128_HW"
-  "#"
-  "&& 1"
-  [(set (match_dup 6)
-       (if_then_else:V2DI (match_dup 1)
-                          (match_dup 7)
-                          (match_dup 8)))
-   (set (match_dup 0)
-       (if_then_else:IEEE128 (ne (match_dup 6)
-                                 (match_dup 8))
-                             (match_dup 4)
-                             (match_dup 5)))]
-{
-  if (GET_CODE (operands[6]) == SCRATCH)
-    operands[6] = gen_reg_rtx (V2DImode);
-
-  operands[7] = CONSTM1_RTX (V2DImode);
-  operands[8] = CONST0_RTX (V2DImode);
-}
- [(set_attr "length" "8")
-  (set_attr "type" "vecperm")])
-
-;; Handle inverting the fpmask comparisons.
-(define_insn_and_split "*mov<mode>cc_invert_p10"
-  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v")
-       (if_then_else:IEEE128
-        (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
-               [(match_operand:IEEE128 2 "altivec_register_operand" "v,v")
-                (match_operand:IEEE128 3 "altivec_register_operand" "v,v")])
-        (match_operand:IEEE128 4 "altivec_register_operand" "v,v")
-        (match_operand:IEEE128 5 "altivec_register_operand" "v,v")))
-   (clobber (match_scratch:V2DI 6 "=0,&v"))]
-  "TARGET_POWER10 && TARGET_FLOAT128_HW"
-  "#"
-  "&& 1"
-  [(set (match_dup 6)
-       (if_then_else:V2DI (match_dup 9)
-                          (match_dup 7)
-                          (match_dup 8)))
-   (set (match_dup 0)
-       (if_then_else:IEEE128 (ne (match_dup 6)
-                                 (match_dup 8))
-                             (match_dup 5)
-                             (match_dup 4)))]
-{
-  rtx op1 = operands[1];
-  enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
-
-  if (GET_CODE (operands[6]) == SCRATCH)
-    operands[6] = gen_reg_rtx (V2DImode);
-
-  operands[7] = CONSTM1_RTX (V2DImode);
-  operands[8] = CONST0_RTX (V2DImode);
-
-  operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
-}
- [(set_attr "length" "8")
-  (set_attr "type" "vecperm")])
-
-(define_insn "*fpmask<mode>"
-  [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
-       (if_then_else:V2DI
-        (match_operator:CCFP 1 "fpmask_comparison_operator"
-               [(match_operand:IEEE128 2 "altivec_register_operand" "v")
-                (match_operand:IEEE128 3 "altivec_register_operand" "v")])
-        (match_operand:V2DI 4 "all_ones_constant" "")
-        (match_operand:V2DI 5 "zero_constant" "")))]
-  "TARGET_POWER10 && TARGET_FLOAT128_HW"
-  "xscmp%V1qp %0,%2,%3"
-  [(set_attr "type" "fpcompare")])
-
-(define_insn "*xxsel<mode>"
-  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
-       (if_then_else:IEEE128
-        (ne (match_operand:V2DI 1 "altivec_register_operand" "v")
-            (match_operand:V2DI 2 "zero_constant" ""))
-        (match_operand:IEEE128 3 "altivec_register_operand" "v")
-        (match_operand:IEEE128 4 "altivec_register_operand" "v")))]
-  "TARGET_POWER10 && TARGET_FLOAT128_HW"
-  "xxsel %x0,%x4,%x3,%x1"
-  [(set_attr "type" "vecmove")])
-
 
 ;; Conversions to and from floating-point.

Reply via email to