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"