This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]