Commit 1aeecaf5 by Hongtao Liu

Fix inefficient vector constructor.

Changelog
gcc/
	PR target/92295
	* config/i386/i386-expand.c (ix86_expand_vector_init_concat)
	Enhance ix86_expand_vector_init_concat.

gcc/testsuite
	* gcc.target/i386/pr92295.c: New test.

From-SVN: r277946
parent 017c6491
2019-11-08 Hongtao Liu <Hongtao.liu@intel.com>
PR target/92295
* config/i386/i386-expand.c (ix86_expand_vector_init_concat)
Enhance ix86_expand_vector_init_concat.
2019-11-08 Joseph Myers <joseph@codesourcery.com> 2019-11-08 Joseph Myers <joseph@codesourcery.com>
* doc/invoke.texi (-Wold-style-definition): Document () not being * doc/invoke.texi (-Wold-style-definition): Document () not being
...@@ -13654,8 +13654,8 @@ static void ...@@ -13654,8 +13654,8 @@ static void
ix86_expand_vector_init_concat (machine_mode mode, ix86_expand_vector_init_concat (machine_mode mode,
rtx target, rtx *ops, int n) rtx target, rtx *ops, int n)
{ {
machine_mode cmode, hmode = VOIDmode, gmode = VOIDmode; machine_mode half_mode = VOIDmode;
rtx first[16], second[8], third[4]; rtx half[2];
rtvec v; rtvec v;
int i, j; int i, j;
...@@ -13665,55 +13665,55 @@ ix86_expand_vector_init_concat (machine_mode mode, ...@@ -13665,55 +13665,55 @@ ix86_expand_vector_init_concat (machine_mode mode,
switch (mode) switch (mode)
{ {
case E_V16SImode: case E_V16SImode:
cmode = V8SImode; half_mode = V8SImode;
break; break;
case E_V16SFmode: case E_V16SFmode:
cmode = V8SFmode; half_mode = V8SFmode;
break; break;
case E_V8DImode: case E_V8DImode:
cmode = V4DImode; half_mode = V4DImode;
break; break;
case E_V8DFmode: case E_V8DFmode:
cmode = V4DFmode; half_mode = V4DFmode;
break; break;
case E_V8SImode: case E_V8SImode:
cmode = V4SImode; half_mode = V4SImode;
break; break;
case E_V8SFmode: case E_V8SFmode:
cmode = V4SFmode; half_mode = V4SFmode;
break; break;
case E_V4DImode: case E_V4DImode:
cmode = V2DImode; half_mode = V2DImode;
break; break;
case E_V4DFmode: case E_V4DFmode:
cmode = V2DFmode; half_mode = V2DFmode;
break; break;
case E_V4SImode: case E_V4SImode:
cmode = V2SImode; half_mode = V2SImode;
break; break;
case E_V4SFmode: case E_V4SFmode:
cmode = V2SFmode; half_mode = V2SFmode;
break; break;
case E_V2DImode: case E_V2DImode:
cmode = DImode; half_mode = DImode;
break; break;
case E_V2SImode: case E_V2SImode:
cmode = SImode; half_mode = SImode;
break; break;
case E_V2DFmode: case E_V2DFmode:
cmode = DFmode; half_mode = DFmode;
break; break;
case E_V2SFmode: case E_V2SFmode:
cmode = SFmode; half_mode = SFmode;
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
if (!register_operand (ops[1], cmode)) if (!register_operand (ops[1], half_mode))
ops[1] = force_reg (cmode, ops[1]); ops[1] = force_reg (half_mode, ops[1]);
if (!register_operand (ops[0], cmode)) if (!register_operand (ops[0], half_mode))
ops[0] = force_reg (cmode, ops[0]); ops[0] = force_reg (half_mode, ops[0]);
emit_insn (gen_rtx_SET (target, gen_rtx_VEC_CONCAT (mode, ops[0], emit_insn (gen_rtx_SET (target, gen_rtx_VEC_CONCAT (mode, ops[0],
ops[1]))); ops[1])));
break; break;
...@@ -13722,16 +13722,16 @@ ix86_expand_vector_init_concat (machine_mode mode, ...@@ -13722,16 +13722,16 @@ ix86_expand_vector_init_concat (machine_mode mode,
switch (mode) switch (mode)
{ {
case E_V4DImode: case E_V4DImode:
cmode = V2DImode; half_mode = V2DImode;
break; break;
case E_V4DFmode: case E_V4DFmode:
cmode = V2DFmode; half_mode = V2DFmode;
break; break;
case E_V4SImode: case E_V4SImode:
cmode = V2SImode; half_mode = V2SImode;
break; break;
case E_V4SFmode: case E_V4SFmode:
cmode = V2SFmode; half_mode = V2SFmode;
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -13742,20 +13742,16 @@ ix86_expand_vector_init_concat (machine_mode mode, ...@@ -13742,20 +13742,16 @@ ix86_expand_vector_init_concat (machine_mode mode,
switch (mode) switch (mode)
{ {
case E_V8DImode: case E_V8DImode:
cmode = V2DImode; half_mode = V4DImode;
hmode = V4DImode;
break; break;
case E_V8DFmode: case E_V8DFmode:
cmode = V2DFmode; half_mode = V4DFmode;
hmode = V4DFmode;
break; break;
case E_V8SImode: case E_V8SImode:
cmode = V2SImode; half_mode = V4SImode;
hmode = V4SImode;
break; break;
case E_V8SFmode: case E_V8SFmode:
cmode = V2SFmode; half_mode = V4SFmode;
hmode = V4SFmode;
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -13766,14 +13762,10 @@ ix86_expand_vector_init_concat (machine_mode mode, ...@@ -13766,14 +13762,10 @@ ix86_expand_vector_init_concat (machine_mode mode,
switch (mode) switch (mode)
{ {
case E_V16SImode: case E_V16SImode:
cmode = V2SImode; half_mode = V8SImode;
hmode = V4SImode;
gmode = V8SImode;
break; break;
case E_V16SFmode: case E_V16SFmode:
cmode = V2SFmode; half_mode = V8SFmode;
hmode = V4SFmode;
gmode = V8SFmode;
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
...@@ -13783,50 +13775,32 @@ ix86_expand_vector_init_concat (machine_mode mode, ...@@ -13783,50 +13775,32 @@ ix86_expand_vector_init_concat (machine_mode mode,
half: half:
/* FIXME: We process inputs backward to help RA. PR 36222. */ /* FIXME: We process inputs backward to help RA. PR 36222. */
i = n - 1; i = n - 1;
j = (n >> 1) - 1; for (j = 1; j != -1; j--)
for (; i > 0; i -= 2, j--)
{ {
first[j] = gen_reg_rtx (cmode); half[j] = gen_reg_rtx (half_mode);
v = gen_rtvec (2, ops[i - 1], ops[i]); switch (n >> 1)
ix86_expand_vector_init (false, first[j],
gen_rtx_PARALLEL (cmode, v));
}
n >>= 1;
if (n > 4)
{
gcc_assert (hmode != VOIDmode);
gcc_assert (gmode != VOIDmode);
for (i = j = 0; i < n; i += 2, j++)
{ {
second[j] = gen_reg_rtx (hmode); case 2:
ix86_expand_vector_init_concat (hmode, second [j], v = gen_rtvec (2, ops[i-1], ops[i]);
&first [i], 2); i -= 2;
} break;
n >>= 1; case 4:
for (i = j = 0; i < n; i += 2, j++) v = gen_rtvec (4, ops[i-3], ops[i-2], ops[i-1], ops[i]);
{ i -= 4;
third[j] = gen_reg_rtx (gmode); break;
ix86_expand_vector_init_concat (gmode, third[j], case 8:
&second[i], 2); v = gen_rtvec (8, ops[i-7], ops[i-6], ops[i-5], ops[i-4],
} ops[i-3], ops[i-2], ops[i-1], ops[i]);
n >>= 1; i -= 8;
ix86_expand_vector_init_concat (mode, target, third, n); break;
} default:
else if (n > 2) gcc_unreachable ();
{
gcc_assert (hmode != VOIDmode);
for (i = j = 0; i < n; i += 2, j++)
{
second[j] = gen_reg_rtx (hmode);
ix86_expand_vector_init_concat (hmode, second [j],
&first [i], 2);
} }
n >>= 1; ix86_expand_vector_init (false, half[j],
ix86_expand_vector_init_concat (mode, target, second, n); gen_rtx_PARALLEL (half_mode, v));
} }
else
ix86_expand_vector_init_concat (mode, target, first, n); ix86_expand_vector_init_concat (mode, target, half, 2);
break; break;
default: default:
......
2019-11-08 Hongtao Liu <hongtao.liu@intel.com>
* gcc.target/i386/pr92295.c: New test.
2019-11-08 Joseph Myers <joseph@codesourcery.com> 2019-11-08 Joseph Myers <joseph@codesourcery.com>
* gcc.dg/c11-old-style-definition-1.c, * gcc.dg/c11-old-style-definition-1.c,
......
/* { dg-do compile } */
/* { dg-options "-O2 -march=skylake-avx512" } */
typedef int X __attribute__((vector_size (32)));
X
foo (int x, int z)
{
X y = { x, x, x, x, z, z, z, z };
return y;
}
/* { dg-final { scan-assembler-times "vpbroadcast" "2" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment