aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-03-13 12:15:06 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-03-13 12:15:06 +0000
commitc40eced02bcfaf28cad7ee97120d7767029f1f6d (patch)
tree0a65db66bff99bc90eccf076a4a59308f90f93f8
parent15ff4345c4be1bb0de1766f58607fbe74325ec87 (diff)
downloadgcc-c40eced02bcfaf28cad7ee97120d7767029f1f6d.zip
gcc-c40eced02bcfaf28cad7ee97120d7767029f1f6d.tar.gz
gcc-c40eced02bcfaf28cad7ee97120d7767029f1f6d.tar.bz2
re PR tree-optimization/56608 (SLP seems to produce incorrect value with -ffast-math)
2013-03-13 Richard Biener <rguenther@suse.de> 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. From-SVN: r196632
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-3.c68
-rw-r--r--gcc/tree-vect-slp.c10
4 files changed, 88 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8008ab6..6a6d572 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-03-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56608
+ * tree-vect-slp.c (vect_schedule_slp): Do not remove scalar
+ calls when vectorizing basic-blocks.
+
2013-03-13 Jakub Jelinek <jakub@redhat.com>
PR plugins/45078
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9fa73be..c08f340 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56608
+ * gcc.dg/vect/fast-math-bb-slp-call-3.c: New testcase.
+
2013-03-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/56611
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 0000000..5878d41
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-3.c
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <math.h>
+
+#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/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 3b2fc80..e184326 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -3181,7 +3181,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; SLP_TREE_SCALAR_STMTS (root).iterate (j, &store)
&& j < SLP_INSTANCE_GROUP_SIZE (instance); j++)