From: Richard Biener Date: Tue, 26 Mar 2013 10:12:52 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.7.3~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5ab9bc86b19e2af3fe7c3c424a11f9fce608c69e;p=thirdparty%2Fgcc.git backport: [multiple changes] 2013-03-26 Richard Biener Backport from mainline 2013-03-13 Richard Biener PR tree-optimization/56608 * tree-vect-slp.c (vect_schedule_slp): Do not remove scalar calls when vectorizing basic-blocks. * gcc.dg/vect/fast-math-bb-slp-call-3.c: New testcase. 2013-03-05 Richard Biener PR tree-optimization/56270 * tree-vect-slp.c (vect_schedule_slp): Clear vectorized stmts of loads after scheduling an SLP instance. * gcc.dg/vect/slp-38.c: New testcase. From-SVN: r197096 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7073f748dc5..cab788451707 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2013-03-26 Richard Biener + + Backport from mainline: + 2013-03-13 Richard Biener + + PR tree-optimization/56608 + * tree-vect-slp.c (vect_schedule_slp): Do not remove scalar + calls when vectorizing basic-blocks. + + 2013-03-05 Richard Biener + + PR tree-optimization/56270 + * tree-vect-slp.c (vect_schedule_slp): Clear vectorized stmts + of loads after scheduling an SLP instance. + 2013-03-26 Walter Lee Backport from mainline: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad0f54170c89..099241559a5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2013-03-26 Richard Biener + + Backport from mainline + 2013-03-13 Richard Biener + + PR tree-optimization/56608 + * gcc.dg/vect/fast-math-bb-slp-call-3.c: New testcase. + + 2013-03-05 Richard Biener + + PR tree-optimization/56270 + * gcc.dg/vect/slp-38.c: New testcase. + 2013-03-25 Oleg Endo Backport from mainline: diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-3.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-3.c new file mode 100644 index 000000000000..5878d418f50c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-3.c @@ -0,0 +1,68 @@ +#include +#include + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +typedef struct { + int initialHeight, initialWidth; + int rotatedHeight, rotatedWidth; + int autoCropHeight, autoCropWidth; +} ufraw_data; + +void __attribute__((noinline,noclone)) +ufraw_test(ufraw_data *uf) +{ + int iWidth = uf->initialWidth; + int iHeight = uf->initialHeight; + double aspectRatio = ((double)iWidth) / iHeight; + double midX = iWidth / 2.0 - 0.5; + double midY = iHeight / 2.0 - 0.5; + double maxX = 0, maxY = 0; + double minX = 999999, minY = 999999; + double lastX = 0, lastY = 0, area = 0; + double scale; + int i; + for (i = 0; i < iWidth + iHeight - 1; i++) + { + int x, y; + if (i < iWidth) { // Trace the left border of the image + x = i; + y = 0; + } else { // Trace the bottom border of the image + x = iWidth - 1; + y = i - iWidth + 1; + } + double srcX = x - midX; + double srcY = y - midY; + // A digital planimeter: + area += srcY * lastX - srcX * lastY; + lastX = srcX; + lastY = srcY; + maxX = MAX(maxX, fabs(srcX)); + maxY = MAX(maxY, fabs(srcY)); + if (fabs(srcX / srcY) > aspectRatio) + minX = MIN(minX, fabs(srcX)); + else + minY = MIN(minY, fabs(srcY)); + } + scale = sqrt((iWidth - 1) * (iHeight - 1) / area); + uf->rotatedWidth = MIN(ceil(2 * maxX + 1.0) * scale, 2 * iWidth); + uf->rotatedHeight = MIN(ceil(2 * maxY + 1.0) * scale, 2 * iHeight); + uf->autoCropWidth = MIN(floor(2 * minX) * scale, 2 * iWidth); + uf->autoCropHeight = MIN(floor(2 * minY) * scale, 2 * iHeight); + if (uf->autoCropWidth != 3) + abort (); +} + +int main() +{ + ufraw_data uf_data; + ufraw_data *uf = &uf_data; + uf->initialWidth = 4; + uf->initialHeight = 5; + ufraw_test(uf); + return 0; +} + +/* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-38.c b/gcc/testsuite/gcc.dg/vect/slp-38.c new file mode 100644 index 000000000000..a387f5d0e063 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-38.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +typedef struct { + float l, h; +} tFPinterval; + +tFPinterval X[1024]; +tFPinterval Y[1024]; +tFPinterval Z[1024]; + +void Compute(void) +{ + int d; + for (d= 0; d < 1024; d++) + { + Y[d].l= X[d].l + X[d].h; + Y[d].h= Y[d].l; + Z[d].l= X[d].l; + Z[d].h= X[d].h; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 1 "vect" { target { vect_float && vect_perm } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 49a4440da4dd..b74f5ebf9adf 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2981,7 +2981,8 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) { VEC (slp_instance, heap) *slp_instances; slp_instance instance; - unsigned int i, vf; + slp_tree loads_node; + unsigned int i, j, vf; bool is_store = false; if (loop_vinfo) @@ -3000,6 +3001,15 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) /* Schedule the tree of INSTANCE. */ is_store = vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance), instance, vf); + + /* Clear STMT_VINFO_VEC_STMT of all loads. With shared loads + between SLP instances we fail to properly initialize the + vectorized SLP stmts and confuse different load permutations. */ + FOR_EACH_VEC_ELT (slp_tree, SLP_INSTANCE_LOADS (instance), j, loads_node) + STMT_VINFO_VEC_STMT + (vinfo_for_stmt + (VEC_index (gimple, SLP_TREE_SCALAR_STMTS (loads_node), 0))) = NULL; + if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS) || vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "vectorizing stmts using SLP."); @@ -3012,7 +3022,15 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) unsigned int j; gimple_stmt_iterator gsi; - vect_remove_slp_scalar_calls (root); + /* Remove scalar call stmts. Do not do this for basic-block + vectorization as not all uses may be vectorized. + ??? Why should this be necessary? DCE should be able to + remove the stmts itself. + ??? For BB vectorization we can as well remove scalar + stmts starting from the SLP tree root if they have no + uses. */ + if (loop_vinfo) + vect_remove_slp_scalar_calls (root); for (j = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (root), j, store) && j < SLP_INSTANCE_GROUP_SIZE (instance); j++)