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]

combine fixes for unordered fp setcc


I wrote a new test to verify that the Right Thing was happening
with some of the m68k patterns I added today.  The change to
combine_simplify_rtx fixes an abort we get there.

Testing that the test case actually runs properly on Alpha, I
noticed that "!__builtin_isunordered(x,y)" was getting compiled to 

	...
        cmpult $31,$0,$0
        xor $0,1,$0

That "cmpult" is alpha-speak for

	(set (reg:DI $0) (ne:DI (reg:DI $0) (const_int 0)))

so it is somewhat curious that we wouldn't simplify that to
EQ when we see the XOR.  Turns out that combine was looking
past some of the FP machinations, and trying to generate

	(eq:DI (reg:DF) (const_double:DF 0.0))
instead of
	(eq:DI (subreg:DI (reg:DF) 0) (const_int 0))

which, incidentally, is not the same thing at all since EQ
is not a bit-for-bit comparison in fp-land (+0.0 == -0.0).
Fixing that is the subject of the simplify_comparison change.


r~


        * combine.c (combine_simplify_rtx): Don't reverse condition
        if there is no reverse for the condition.
        (simplify_comparison): Don't simplify subregs from INT to FP.

        * gcc.c-torture/execute/ieee/fp-cmp-4.c (main): Make "data" static.
        * gcc.c-torture/execute/ieee/fp-cmp-5.c: New.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.232
diff -c -p -d -u -r1.232 combine.c
--- combine.c	2001/08/22 14:34:47	1.232
+++ combine.c	2001/08/28 00:56:10
@@ -3636,7 +3636,8 @@ combine_simplify_rtx (x, op0_mode, last,
 		 just make the comparison operation.  */
 	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
 		x = gen_binary (cond_code, mode, cond, cop1);
-	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx)
+	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
+		       && reverse_condition (cond_code) != UNKNOWN)
 		x = gen_binary (reverse_condition (cond_code),
 				mode, cond, cop1);
 
@@ -10828,6 +10829,7 @@ simplify_comparison (code, pop0, pop1)
 
   if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
       && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
+      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
       && (code == NE || code == EQ)
       && ((GET_MODE_SIZE (GET_MODE (op0))
 	   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))))
@@ -10838,6 +10840,7 @@ simplify_comparison (code, pop0, pop1)
 
   else if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
 	   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
+	   && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
 	   && (code == NE || code == EQ)
 	   && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
 	       <= HOST_BITS_PER_WIDE_INT)
Index: testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c,v
retrieving revision 1.1
diff -c -p -d -u -r1.1 fp-cmp-4.c
--- fp-cmp-4.c	2000/01/24 20:10:04	1.1
+++ fp-cmp-4.c	2001/08/28 00:56:11
@@ -104,7 +104,7 @@ main()
     unsigned lg : 1;
   };
 
-  const struct try data[] =
+  static struct try const data[] =
   {
     { NAN, NAN, 1, 0, 0, 0, 0, 0 },
     { 0.0, NAN, 1, 0, 0, 0, 0, 0 },
Index: testsuite/gcc.c-torture/execute/ieee/fp-cmp-5.c
===================================================================
RCS file: fp-cmp-5.c
diff -N fp-cmp-5.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ fp-cmp-5.c	Mon Aug 27 17:56:11 2001
@@ -0,0 +1,131 @@
+/* Like fp-cmp-4.c, but test that the setcc patterns are correct.  */
+
+static int
+test_isunordered(double x, double y)
+{
+  return __builtin_isunordered(x, y);
+}
+
+static int
+test_not_isunordered(double x, double y)
+{
+  return !__builtin_isunordered(x, y);
+}
+
+static int
+test_isless(double x, double y)
+{
+  return __builtin_isless(x, y);
+}
+
+static int
+test_not_isless(double x, double y)
+{
+  return !__builtin_isless(x, y);
+}
+
+static int
+test_islessequal(double x, double y)
+{
+  return __builtin_islessequal(x, y);
+}
+
+static int
+test_not_islessequal(double x, double y)
+{
+  return !__builtin_islessequal(x, y);
+}
+
+static int
+test_isgreater(double x, double y)
+{
+  return __builtin_isgreater(x, y);
+}
+
+static int
+test_not_isgreater(double x, double y)
+{
+  return !__builtin_isgreater(x, y);
+}
+
+static int
+test_isgreaterequal(double x, double y)
+{
+  return __builtin_isgreaterequal(x, y);
+}
+
+static int
+test_not_isgreaterequal(double x, double y)
+{
+  return !__builtin_isgreaterequal(x, y);
+}
+
+static int
+test_islessgreater(double x, double y)
+{
+  return __builtin_islessgreater(x, y);
+}
+
+static int
+test_not_islessgreater(double x, double y)
+{
+  return !__builtin_islessgreater(x, y);
+}
+
+static void
+one_test(double x, double y, int expected,
+         int (*pos) (double, double), int (*neg) (double, double))
+{
+  if ((*pos)(x, y) != expected)
+    abort ();
+  if ((*neg)(x, y) != !expected)
+    abort ();
+}
+
+#define NAN (0.0 / 0.0)
+
+int
+main()
+{
+  struct try
+  {
+    double x, y;
+    int result[6];
+  };
+
+  static struct try const data[] =
+  {
+    { NAN, NAN, { 1, 0, 0, 0, 0, 0 } },
+    { 0.0, NAN, { 1, 0, 0, 0, 0, 0 } },
+    { NAN, 0.0, { 1, 0, 0, 0, 0, 0 } },
+    { 0.0, 0.0, { 0, 0, 1, 0, 1, 0 } },
+    { 1.0, 2.0, { 0, 1, 1, 0, 0, 1 } },
+    { 2.0, 1.0, { 0, 0, 0, 1, 1, 1 } },
+  };
+
+  struct test
+  {
+    int (*pos)(double, double);
+    int (*neg)(double, double);
+  };
+
+  static struct test const tests[] =
+  {
+    { test_isunordered, test_not_isunordered },
+    { test_isless, test_not_isless },
+    { test_islessequal, test_not_islessequal },
+    { test_isgreater, test_not_isgreater },
+    { test_isgreaterequal, test_not_isgreaterequal },
+    { test_islessgreater, test_not_islessgreater }
+  };
+
+  const int n = sizeof(data) / sizeof(data[0]);
+  int i, j;
+
+  for (i = 0; i < n; ++i)
+    for (j = 0; j < 6; ++j)
+      one_test (data[i].x, data[i].y, data[i].result[j],
+		tests[j].pos, tests[j].neg);
+
+  exit (0);
+}


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