https://gcc.gnu.org/g:b96c5436880d7926299314a33c953171082ab59e
commit r14-9523-gb96c5436880d7926299314a33c953171082ab59e Author: Uros Bizjak <ubiz...@gmail.com> Date: Mon Mar 18 20:40:29 2024 +0100 i386: Unify {general,timode}_scalar_chain::convert_op [PR111822] Recent PR111822 fix implemented REG_EH_REGION note copying to a STV converted preload instruction in general_scalar_chain::convert_op. However, the same issue remains in timode_scalar_chain::convert_op. Instead of copying the newly introduced code to timode_scalar_chain::convert_op, the patch unifies both functions to a common function. PR target/111822 gcc/ChangeLog: * config/i386/i386-features.cc (smode_convert_cst): New function to handle SImode, DImode and TImode immediates, generalized from timode_convert_cst. (timode_convert_cst): Remove. (scalar_chain::convert_op): Unify from general_scalar_chain::convert_op and timode_scalar_chain::convert_op. (general_scalar_chain::convert_op): Remove. (timode_scalar_chain::convert_op): Remove. (timode_scalar_chain::convert_insn): Update the call to renamed timode_convert_cst. * config/i386/i386-features.h (class scalar_chain): Redeclare convert_op as protected class member. (class general_calar_chain): Remove convert_op. (class timode_scalar_chain): Ditto. gcc/testsuite/ChangeLog: * g++.target/i386/pr111822.C (dg-do): Compile only for ia32 targets. (dg-options): Add -march=x86-64. Diff: --- gcc/config/i386/i386-features.cc | 127 +++++++++---------------------- gcc/config/i386/i386-features.h | 4 +- gcc/testsuite/g++.target/i386/pr111822.C | 4 +- 3 files changed, 40 insertions(+), 95 deletions(-) diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index c7d7a965901..e3e004d5526 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -980,14 +980,35 @@ scalar_chain::convert_reg (rtx_insn *insn, rtx dst, rtx src) REGNO (src), REGNO (dst), INSN_UID (insn)); } +/* Helper function to convert immediate constant X to vmode. */ +static rtx +smode_convert_cst (rtx x, enum machine_mode vmode) +{ + /* Prefer all ones vector in case of -1. */ + if (constm1_operand (x, GET_MODE (x))) + return CONSTM1_RTX (vmode); + + unsigned n = GET_MODE_NUNITS (vmode); + rtx *v = XALLOCAVEC (rtx, n); + v[0] = x; + for (unsigned i = 1; i < n; ++i) + v[i] = const0_rtx; + return gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (n, v)); +} + /* Convert operand OP in INSN. We should handle memory operands and uninitialized registers. All other register uses are converted during registers conversion. */ void -general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) +scalar_chain::convert_op (rtx *op, rtx_insn *insn) { + rtx tmp; + + if (GET_MODE (*op) == V1TImode) + return; + *op = copy_rtx_if_shared (*op); if (GET_CODE (*op) == NOT @@ -998,20 +1019,21 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } else if (MEM_P (*op)) { - rtx_insn* eh_insn, *movabs = NULL; - rtx tmp = gen_reg_rtx (GET_MODE (*op)); + rtx_insn *movabs = NULL; /* Emit MOVABS to load from a 64-bit absolute address to a GPR. */ if (!memory_operand (*op, GET_MODE (*op))) { - rtx tmp2 = gen_reg_rtx (GET_MODE (*op)); - movabs = emit_insn_before (gen_rtx_SET (tmp2, *op), insn); + tmp = gen_reg_rtx (GET_MODE (*op)); + movabs = emit_insn_before (gen_rtx_SET (tmp, *op), insn); - *op = tmp2; + *op = tmp; } - eh_insn - = emit_insn_before (gen_rtx_SET (gen_rtx_SUBREG (vmode, tmp, 0), + tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (GET_MODE (*op)), 0); + + rtx_insn *eh_insn + = emit_insn_before (gen_rtx_SET (copy_rtx (tmp), gen_gpr_to_xmm_move_src (vmode, *op)), insn); @@ -1028,33 +1050,17 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } } - *op = gen_rtx_SUBREG (vmode, tmp, 0); + *op = tmp; if (dump_file) fprintf (dump_file, " Preloading operand for insn %d into r%d\n", INSN_UID (insn), REGNO (tmp)); } else if (REG_P (*op)) + *op = gen_rtx_SUBREG (vmode, *op, 0); + else if (CONST_SCALAR_INT_P (*op)) { - *op = gen_rtx_SUBREG (vmode, *op, 0); - } - else if (CONST_INT_P (*op)) - { - rtx vec_cst; - rtx tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (smode), 0); - - /* Prefer all ones vector in case of -1. */ - if (constm1_operand (*op, GET_MODE (*op))) - vec_cst = CONSTM1_RTX (vmode); - else - { - unsigned n = GET_MODE_NUNITS (vmode); - rtx *v = XALLOCAVEC (rtx, n); - v[0] = *op; - for (unsigned i = 1; i < n; ++i) - v[i] = const0_rtx; - vec_cst = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (n, v)); - } + rtx vec_cst = smode_convert_cst (*op, vmode); if (!standard_sse_constant_p (vec_cst, vmode)) { @@ -1065,6 +1071,8 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) emit_insn_before (seq, insn); } + tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (smode), 0); + emit_insn_before (gen_move_insn (copy_rtx (tmp), vec_cst), insn); *op = tmp; } @@ -1767,67 +1775,6 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg) } } -/* Helper function to convert immediate constant X to V1TImode. */ -static rtx -timode_convert_cst (rtx x) -{ - /* Prefer all ones vector in case of -1. */ - if (constm1_operand (x, TImode)) - return CONSTM1_RTX (V1TImode); - - rtx *v = XALLOCAVEC (rtx, 1); - v[0] = x; - return gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec_v (1, v)); -} - -/* Convert operand OP in INSN from TImode to V1TImode. */ - -void -timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) -{ - if (GET_MODE (*op) == V1TImode) - return; - - *op = copy_rtx_if_shared (*op); - - if (REG_P (*op)) - *op = gen_rtx_SUBREG (V1TImode, *op, 0); - else if (MEM_P (*op)) - { - rtx tmp = gen_reg_rtx (V1TImode); - emit_insn_before (gen_rtx_SET (tmp, - gen_gpr_to_xmm_move_src (V1TImode, *op)), - insn); - *op = tmp; - - if (dump_file) - fprintf (dump_file, " Preloading operand for insn %d into r%d\n", - INSN_UID (insn), REGNO (tmp)); - } - else if (CONST_SCALAR_INT_P (*op)) - { - rtx tmp = gen_reg_rtx (V1TImode); - rtx vec_cst = timode_convert_cst (*op); - - if (!standard_sse_constant_p (vec_cst, V1TImode)) - { - start_sequence (); - vec_cst = validize_mem (force_const_mem (V1TImode, vec_cst)); - rtx_insn *seq = get_insns (); - end_sequence (); - emit_insn_before (seq, insn); - } - - emit_insn_before (gen_move_insn (tmp, vec_cst), insn); - *op = tmp; - } - else - { - gcc_assert (SUBREG_P (*op)); - gcc_assert (GET_MODE (*op) == vmode); - } -} - /* Convert INSN from TImode to V1T1mode. */ void @@ -1892,7 +1839,7 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) } else { - src = timode_convert_cst (src); + src = smode_convert_cst (src, V1TImode); src = validize_mem (force_const_mem (V1TImode, src)); use_move = MEM_P (dst); } diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h index b259cf679af..fbf72377afb 100644 --- a/gcc/config/i386/i386-features.h +++ b/gcc/config/i386/i386-features.h @@ -170,13 +170,13 @@ class scalar_chain void convert_insn_common (rtx_insn *insn); void make_vector_copies (rtx_insn *, rtx); void convert_registers (); + void convert_op (rtx *op, rtx_insn *insn); private: bool add_insn (bitmap candidates, unsigned insn_uid, bitmap disallowed); bool analyze_register_chain (bitmap candidates, df_ref ref, bitmap disallowed); virtual void convert_insn (rtx_insn *insn) = 0; - virtual void convert_op (rtx *op, rtx_insn *insn) = 0; }; class general_scalar_chain : public scalar_chain @@ -188,7 +188,6 @@ class general_scalar_chain : public scalar_chain private: void convert_insn (rtx_insn *insn) final override; - void convert_op (rtx *op, rtx_insn *insn) final override; int vector_const_cost (rtx exp); rtx convert_rotate (enum rtx_code, rtx op0, rtx op1, rtx_insn *insn); }; @@ -202,7 +201,6 @@ class timode_scalar_chain : public scalar_chain private: void fix_debug_reg_uses (rtx reg); void convert_insn (rtx_insn *insn) final override; - void convert_op (rtx *op, rtx_insn *insn) final override; }; } // anon namespace diff --git a/gcc/testsuite/g++.target/i386/pr111822.C b/gcc/testsuite/g++.target/i386/pr111822.C index d405387b23c..0829c91f270 100644 --- a/gcc/testsuite/g++.target/i386/pr111822.C +++ b/gcc/testsuite/g++.target/i386/pr111822.C @@ -1,6 +1,6 @@ /* PR target/111822 */ -/* { dg-do compile } */ -/* { dg-options "-O2 -flive-range-shrinkage -fno-dce -fnon-call-exceptions" } */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2 -flive-range-shrinkage -fno-dce -fnon-call-exceptions -march=x86-64" } */ typedef union { int *pNativeClosure;