re PR tree-optimization/59354 (Element swizzling produces invalid result with -O3)

2015-01-14  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/59354
	* tree-vect-slp.c (vect_build_slp_tree_1): Treat loads from
	groups larger than the slp group size as having gaps.

	* gcc.dg/vect/pr59354.c: New testcase.

From-SVN: r219603
This commit is contained in:
Richard Biener 2015-01-14 14:06:07 +00:00 committed by Richard Biener
parent 7d11e4d632
commit 7ef95f9cf0
4 changed files with 51 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2015-01-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/59354
* tree-vect-slp.c (vect_build_slp_tree_1): Treat loads from
groups larger than the slp group size as having gaps.
2015-01-14 Andrew MacLeod <amacleod@redhat.com>
PR middle-end/59448

View File

@ -1,3 +1,8 @@
2015-01-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/59354
* gcc.dg/vect/pr59354.c: New testcase.
2015-01-14 Andrew Stubbs <ams@codesourcery.com>
* lib/target-supports.exp

View File

@ -0,0 +1,35 @@
/* { dg-do run } */
/* { dg-additional-options "-O3" } */
#include "tree-vect.h"
void abort (void);
unsigned int a[256];
unsigned char b[256];
int main()
{
int i, z, x, y;
check_vect ();
for(i = 0; i < 256; i++)
{
a[i] = i % 5;
__asm__ volatile ("");
}
for (z = 0; z < 16; z++)
for (y = 0; y < 4; y++)
for (x = 0; x < 4; x++)
b[y*64 + z*4 + x] = a[z*16 + y*4 + x];
if (b[4] != 1)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump "vectorized 1 loop" "vect" { target { vect_pack_trunc } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -729,8 +729,11 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
??? We should enhance this to only disallow gaps
inside vectors. */
if ((unrolling_factor > 1
&& GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
&& ((GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
/* If the group is split up then GROUP_GAP
isn't correct here, nor is GROUP_FIRST_ELEMENT. */
|| GROUP_SIZE (vinfo_for_stmt (stmt)) > group_size))
|| (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
{