From d067e238cbf20a659f024b342253230b28eb5a7f Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Tue, 10 May 2016 16:08:42 +0000 Subject: [PATCH] re PR target/70799 (STV pass does not convert DImode shifts) gcc/ PR target/70799 * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow integer constants. (dimode_scalar_chain::vector_const_cost): New. (dimode_scalar_chain::compute_convert_gain): Handle constants. (dimode_scalar_chain::convert_op): Likewise. (dimode_scalar_chain::convert_insn): Likewise. gcc/testsuite/ PR target/70799 * gcc.target/i386/pr70799-1.c: New test. From-SVN: r236090 --- gcc/ChangeLog | 10 ++++ gcc/config/i386/i386.c | 70 +++++++++++++++++++++-- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/pr70799-1.c | 41 +++++++++++++ 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr70799-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 562d303ca6a..a2257cea32c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-05-10 Ilya Enkovich + + PR target/70799 + * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow + integer constants. + (dimode_scalar_chain::vector_const_cost): New. + (dimode_scalar_chain::compute_convert_gain): Handle constants. + (dimode_scalar_chain::convert_op): Likewise. + (dimode_scalar_chain::convert_insn): Likewise. + 2016-05-10 Pierre-Marie de Rodat * dwarf2out.c (resolve_args_picking_1): Consider DW_OP_neg as an diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 05476f37449..530a6e84a0c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2789,7 +2789,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn) return convertible_comparison_p (insn); /* We are interested in DImode promotion only. */ - if (GET_MODE (src) != DImode + if ((GET_MODE (src) != DImode + && !CONST_INT_P (src)) || GET_MODE (dst) != DImode) return false; @@ -2809,24 +2810,31 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn) return true; case MEM: + case CONST_INT: return REG_P (dst); default: return false; } - if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)) + if (!REG_P (XEXP (src, 0)) + && !MEM_P (XEXP (src, 0)) + && !CONST_INT_P (XEXP (src, 0)) /* Check for andnot case. */ && (GET_CODE (src) != AND || GET_CODE (XEXP (src, 0)) != NOT || !REG_P (XEXP (XEXP (src, 0), 0)))) return false; - if (!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1))) + if (!REG_P (XEXP (src, 1)) + && !MEM_P (XEXP (src, 1)) + && !CONST_INT_P (XEXP (src, 1))) return false; - if (GET_MODE (XEXP (src, 0)) != DImode - || GET_MODE (XEXP (src, 1)) != DImode) + if ((GET_MODE (XEXP (src, 0)) != DImode + && !CONST_INT_P (XEXP (src, 0))) + || (GET_MODE (XEXP (src, 1)) != DImode + && !CONST_INT_P (XEXP (src, 1)))) return false; return true; @@ -3120,6 +3128,7 @@ class dimode_scalar_chain : public scalar_chain void convert_reg (unsigned regno); void make_vector_copies (unsigned regno); void convert_registers (); + int vector_const_cost (rtx exp); }; class timode_scalar_chain : public scalar_chain @@ -3328,6 +3337,19 @@ scalar_chain::build (bitmap candidates, unsigned insn_uid) BITMAP_FREE (queue); } +/* Return a cost of building a vector costant + instead of using a scalar one. */ + +int +dimode_scalar_chain::vector_const_cost (rtx exp) +{ + gcc_assert (CONST_INT_P (exp)); + + if (standard_sse_constant_p (exp, V2DImode)) + return COSTS_N_INSNS (1); + return ix86_cost->sse_load[1]; +} + /* Compute a gain for chain conversion. */ int @@ -3359,11 +3381,25 @@ dimode_scalar_chain::compute_convert_gain () || GET_CODE (src) == IOR || GET_CODE (src) == XOR || GET_CODE (src) == AND) - gain += ix86_cost->add; + { + gain += ix86_cost->add; + if (CONST_INT_P (XEXP (src, 0))) + gain -= vector_const_cost (XEXP (src, 0)); + if (CONST_INT_P (XEXP (src, 1))) + gain -= vector_const_cost (XEXP (src, 1)); + } else if (GET_CODE (src) == COMPARE) { /* Assume comparison cost is the same. */ } + else if (GET_CODE (src) == CONST_INT) + { + if (REG_P (dst)) + gain += COSTS_N_INSNS (2); + else if (MEM_P (dst)) + gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1]; + gain -= vector_const_cost (src); + } else gcc_unreachable (); } @@ -3639,6 +3675,24 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } *op = gen_rtx_SUBREG (V2DImode, *op, 0); } + else if (CONST_INT_P (*op)) + { + rtx vec_cst; + rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0); + + /* Prefer all ones vector in case of -1. */ + if (constm1_operand (*op, GET_MODE (*op))) + vec_cst = CONSTM1_RTX (V2DImode); + else + vec_cst = gen_rtx_CONST_VECTOR (V2DImode, + gen_rtvec (2, *op, const0_rtx)); + + if (!standard_sse_constant_p (vec_cst, V2DImode)) + vec_cst = validize_mem (force_const_mem (V2DImode, vec_cst)); + + emit_insn_before (gen_move_insn (tmp, vec_cst), insn); + *op = tmp; + } else { gcc_assert (SUBREG_P (*op)); @@ -3711,6 +3765,10 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn) UNSPEC_PTEST); break; + case CONST_INT: + convert_op (&src, insn); + break; + default: gcc_unreachable (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 36b8e2f926d..7ab92a51390 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-10 Ilya Enkovich + + PR target/70799 + * gcc.target/i386/pr70799-1.c: New test. + 2016-05-10 Pierre-Marie de Rodat * gnat.dg/debug6.adb, gnat.dg/debug6_pkg.ads: New testcase. diff --git a/gcc/testsuite/gcc.target/i386/pr70799-1.c b/gcc/testsuite/gcc.target/i386/pr70799-1.c new file mode 100644 index 00000000000..0abbfb9fe79 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70799-1.c @@ -0,0 +1,41 @@ +/* PR target/pr70799 */ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2 -march=slm" } */ +/* { dg-final { scan-assembler "pxor" } } */ +/* { dg-final { scan-assembler "pcmpeqd" } } */ +/* { dg-final { scan-assembler "movdqa\[ \\t\]+.LC0" } } */ + +long long a, b, c; + +void test1 (void) +{ + long long t; + if (a) + t = 0LL; + else + t = b; + a = c & t; + b = c | t; +} + +void test2 (void) +{ + long long t; + if (a) + t = -1LL; + else + t = b; + a = c & t; + b = c | t; +} + +void test3 (void) +{ + long long t; + if (a) + t = 0xf0f0f0f0f0f0f0f0LL; + else + t = b; + a = c & t; + b = c | t; +} -- 2.30.2