https://gcc.gnu.org/g:2c9a83413db78aba0b788b199cbf94d69f71f6bd

commit 2c9a83413db78aba0b788b199cbf94d69f71f6bd
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Fri Apr 12 14:37:52 2024 -0400

    Simplify converting between SImode and SF/DFmode.
    
    2024-04-12  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            PR target/90822
            * gcc/config/rs6000.md (uns code attribute): Add sign_extend and
            zero_extend.
            (floatsidf2): If SImode can live in the floating point registers,
            directly issue a conversion to DImode and do the floating point
            conversion during expansion instead of using an UNSPEC.
            (floatunssisf2): Likewise.
            (floatunssidf2): Likewise.
            (floatsisf2): Likewise.
            * gcc/config/rs6000/vsx.md (vsx_extract_si_<uns>float_df): Adjust
            combiner to expect sign/zero extend of SImode to DImode in 
optimizing
            V4SI extracts.

Diff:
---
 gcc/config/rs6000/rs6000.md | 48 ++++++++++++++++++++++++++++++++++++++++-----
 gcc/config/rs6000/vsx.md    | 18 +++++++++--------
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f1f120199f3..4ff80c34cb1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -667,7 +667,9 @@
 (define_code_attr uns [(fix            "")
                       (unsigned_fix    "uns")
                       (float           "")
-                      (unsigned_float  "uns")])
+                      (unsigned_float  "uns")
+                      (sign_extend     "")
+                      (zero_extend     "uns")])
 
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
@@ -6041,6 +6043,10 @@
 ; with a '#' template, and a define_split (with C code).  The idea is
 ; to allow constant folding with the template of the define_insn,
 ; then to have the insns split later (between sched1 and final).
+;
+; If we have direct support for SImode in floating point registers, just
+; convert the SImode value to DImode.  If we are loading the value from memory,
+; we will use the LFIWAX/LXSIWAX
 
 (define_expand "floatsidf2"
   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
@@ -6054,7 +6060,13 @@
 {
   if (TARGET_LFIWAX && TARGET_FCFID)
     {
-      emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
+      if (TARGET_POWERPC64 && TARGET_P8_VECTOR)
+       {
+         rtx di_tmp = convert_to_mode (DImode, operands[1], false);
+         emit_insn (gen_floatdidf2 (operands[0], di_tmp));
+       }
+      else
+       emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
       DONE;
     }
   else if (TARGET_FCFID)
@@ -6110,6 +6122,10 @@
 ;; If we don't have a direct conversion to single precision, don't enable this
 ;; conversion for 32-bit without fast math, because we don't have the insn to
 ;; generate the fixup swizzle to avoid double rounding problems.
+;
+; If we have direct support for SImode in floating point registers, just
+; convert the SImode value to DImode.  If we are loading the value from memory,
+; we will use the LFIWAX/LXSIWAX
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand")
         (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
@@ -6120,7 +6136,13 @@
 {
   if (TARGET_LFIWZX && TARGET_FCFIDUS)
     {
-      emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
+      if (TARGET_POWERPC64 && TARGET_P8_VECTOR)
+       {
+         rtx di_tmp = convert_to_mode (DImode, operands[1], true);
+         emit_insn (gen_floatdisf2 (operands[0], di_tmp));
+       }
+      else
+       emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
       DONE;
     }
   else
@@ -6145,7 +6167,13 @@
 {
   if (TARGET_LFIWZX && TARGET_FCFID)
     {
-      emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
+      if (TARGET_POWERPC64 && TARGET_P8_VECTOR)
+       {
+         rtx di_tmp = convert_to_mode (DImode, operands[1], true);
+         emit_insn (gen_floatdidf2 (operands[0], di_tmp));
+       }
+      else
+       emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
       DONE;
     }
   else if (TARGET_FCFID)
@@ -6905,6 +6933,10 @@
 ;; If we don't have a direct conversion to single precision, don't enable this
 ;; conversion for 32-bit without fast math, because we don't have the insn to
 ;; generate the fixup swizzle to avoid double rounding problems.
+;
+; If we have direct support for SImode in floating point registers, just
+; convert the SImode value to DImode.  If we are loading the value from memory,
+; we will use the LFIWAX/LXSIWAX
 (define_expand "floatsisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand")
         (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
@@ -6915,7 +6947,13 @@
 {
   if (TARGET_FCFIDS && TARGET_LFIWAX)
     {
-      emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
+      if (TARGET_POWERPC64 && TARGET_P8_VECTOR)
+       {
+         rtx di_tmp = convert_to_mode (DImode, operands[1], false);
+         emit_insn (gen_floatdisf2 (operands[0], di_tmp));
+       }
+      else
+       emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
       DONE;
     }
   else if (TARGET_FCFID && TARGET_LFIWAX)
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index f135fa079bd..2be5303d572 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4319,10 +4319,11 @@
 ;; Get the element into the top position and use XVCVSWDP/XVCVUWDP
 (define_insn_and_split "*vsx_extract_si_<uns>float_df"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=wa")
-       (any_float:DF
-        (vec_select:SI
-         (match_operand:V4SI 1 "gpc_reg_operand" "v")
-         (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")]))))
+       (float:DF
+        (any_extend:DI
+         (vec_select:SI
+          (match_operand:V4SI 1 "gpc_reg_operand" "v")
+          (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")])))))
    (clobber (match_scratch:V4SI 3 "=v"))]
   "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
   "#"
@@ -4362,10 +4363,11 @@
 ;; type.
 (define_insn_and_split "*vsx_extract_si_<uns>float_<mode>"
   [(set (match_operand:VSX_EXTRACT_FL 0 "gpc_reg_operand" "=wa")
-       (any_float:VSX_EXTRACT_FL
-        (vec_select:SI
-         (match_operand:V4SI 1 "gpc_reg_operand" "v")
-         (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")]))))
+       (float:VSX_EXTRACT_FL
+        (any_extend:DI
+         (vec_select:SI
+          (match_operand:V4SI 1 "gpc_reg_operand" "v")
+          (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n")])))))
    (clobber (match_scratch:V4SI 3 "=v"))
    (clobber (match_scratch:DF 4 "=wa"))]
   "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"

Reply via email to