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
This commit is contained in:
parent
1e3af2a4e0
commit
d067e238cb
4 changed files with 120 additions and 6 deletions
|
@ -1,3 +1,13 @@
|
|||
2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
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 <derodat@adacore.com>
|
||||
|
||||
* dwarf2out.c (resolve_args_picking_1): Consider DW_OP_neg as an
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
PR target/70799
|
||||
* gcc.target/i386/pr70799-1.c: New test.
|
||||
|
||||
2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
|
||||
|
||||
* gnat.dg/debug6.adb, gnat.dg/debug6_pkg.ads: New testcase.
|
||||
|
|
41
gcc/testsuite/gcc.target/i386/pr70799-1.c
Normal file
41
gcc/testsuite/gcc.target/i386/pr70799-1.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue