This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
combine fixes for unordered fp setcc
- To: gcc-patches at gcc dot gnu dot org
- Subject: combine fixes for unordered fp setcc
- From: Richard Henderson <rth at redhat dot com>
- Date: Mon, 27 Aug 2001 18:09:45 -0700
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);
+}