This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH [target/rs6000]: pr30485
- From: Josh Conner <jconner at apple dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 16 Jan 2007 14:47:40 -0800
- Subject: PATCH [target/rs6000]: pr30485
The rs6000-backend function "rs6000_emit_vector_compare" is unable to
handle unordered floating point comparisons (e.g., UNLE). In the case
where this showed up (compiling test gcc.dg/vect/pr23816-1.c), it was
occurring because ifcvt was performing an "invert_tree_comparison" from
a GT_EXPR to a UNLE_EXPR, and the tree vectorizer was allowing the
resultant unordered expression to be vectorized.
I briefly considered trying to disallow the frontend from vectorizing
this example, but a) I couldn't find a distinction in the backend
interface that would allow us to tell whether there was vectorizer
support for unordered instructions, and b) I was able to keep these
calls as vector instructions by re-inverting them in the backend vectorizer.
The attached patch was bootstrapped and tested on powerpc-apple-darwin
with c,c++,objc,obj-c++ and no regressions.
OK for mainline?
- Josh
2007-01-16 Josh Conner <jconner@apple.com>
PR target/30485
* config/rs6000/rs6000.c (rs6000_emit_vector_compare): Add
support for UNLE, UNLT, UNGE, and UNGT.
2007-01-16 Josh Conner <jconner@apple.com>
PR target/30485
* gcc.dg/vect/vect.exp: Add support for no-trapping-math tests.
* gcc.dg/vect/no-trapping-math-1: New.
* gcc.dg/vect/no-trapping-math-2: New.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 120830)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -11890,10 +11890,37 @@ rs6000_emit_vector_compare (enum rtx_cod
try_again = true;
break;
case NE:
- /* Treat A != B as ~(A==B). */
+ case UNLE:
+ case UNLT:
+ case UNGE:
+ case UNGT:
+ /* Invert condition and try again.
+ e.g., A != B becomes ~(A==B). */
{
+ enum rtx_code rev_code;
enum insn_code nor_code;
- rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
+
+ switch (rcode)
+ {
+ case NE:
+ rev_code = EQ;
+ break;
+ case UNLE:
+ rev_code = GT;
+ break;
+ case UNLT:
+ rev_code = GE;
+ break;
+ case UNGE:
+ rev_code = LT;
+ break;
+ case UNGT:
+ rev_code = LE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ rtx eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
dest_mode);
nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
Index: gcc/testsuite/gcc.dg/vect/vect.exp
===================================================================
--- gcc/testsuite/gcc.dg/vect/vect.exp (revision 120830)
+++ gcc/testsuite/gcc.dg/vect/vect.exp (working copy)
@@ -150,6 +150,12 @@ lappend DEFAULT_VECTCFLAGS "-funswitch-l
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/unswitch-loops-*.\[cS\]]] \
"" $DEFAULT_VECTCFLAGS
+# -fno-trapping-math tests
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "-fno-trapping-math"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-trapping-math-*.\[cS\]]] \
+ "" $DEFAULT_VECTCFLAGS
+
# With -Os
lappend DEFAULT_VECTCFLAGS "-Os"
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/Os-vect-*.\[cS\]]] \
Index: gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c
===================================================================
--- gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c (revision 0)
+++ gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c (revision 0)
@@ -0,0 +1,12 @@
+/* Test for pr30485. */
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_condition } */
+void
+foo (float a[32], float b[2][32])
+{
+ int i;
+ for (i = 0; i < 32; i++)
+ a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i];
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
Index: gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c
===================================================================
--- gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c (revision 0)
@@ -0,0 +1,39 @@
+/* Test for pr30485. */
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int
+main1 (void)
+{
+ int i;
+ float a[N];
+ float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+ /* Condition in loop. */
+ /* This loop is vectorized on platforms that support vect_condition. */
+ for (i = 0; i < N; i++)
+ {
+ a[i] = (b[i] > 0 ? b[i] : 0);
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != b[i])
+ abort ();
+ }
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+ return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target powerpc*-*-* } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target i?86-*-* x86_64-*-* ia64-*-* } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */