This patch fixes PR 53487, so that -misel will no longer cause an unknown insn
error. Andrew Pinksi's changes on May 4th, 2012, changed to use the
mov<mode>cc pattern instead of the cstore<mode>4 in some cases, when a target
machine defines both patterns. The cstore<mode>4 pattern had checks in it to
prevent ISELs involving floating point compares from being generated, but
mov<mode>cc did not. In addition, building Spec showed that going through
mov<mode>cc also needed to make sure a comparison against a negative integer
constant like cstore<mode>4 also had.
I have bootstrapped the compiler (using BOOT_CFLAGS='-g -O2 -mcpu=power7
-misel) and there were no regressions in the test suite against an unpatched
compiler. I have also built the Spec 2006 suite with isel, and it generated no
errors. Is this patch ok to apply?
[gcc]
2012-06-04 Michael Meissner <[email protected]>
PR target/53487
* config/rs6000/rs6000.c (rs6000_generate_compare): If we are
doing an unsigned compare, make sure the second argument is not a
negative constant.
(rs6000_emit_cmove): Don't allow floating point comparisons when
generating ISEL moves.
[gcc/testsuite]
2012-06-04 Michael Meissner <[email protected]>
* gcc.target/powerpc/pr53487.c: New test.
--
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
[email protected] fax +1 (978) 399-6899
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 188186)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -15361,6 +15361,16 @@ rs6000_generate_compare (rtx cmp, enum m
else
comp_mode = CCmode;
+ /* If we have an unsigned compare, make sure we don't have a signed value as
+ an immediate. */
+ if (comp_mode == CCUNSmode && GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) < 0)
+ {
+ op0 = copy_rtx_if_shared (op0);
+ op1 = force_reg (GET_MODE (op0), op1);
+ cmp = gen_rtx_fmt_ee (code, GET_MODE (cmp), op0, op1);
+ }
+
/* First, the compare. */
compare_result = gen_reg_rtx (comp_mode);
@@ -16114,6 +16124,11 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx
if (GET_MODE (false_cond) != result_mode)
return 0;
+ /* Don't allow using floating point comparisons for integer results for
+ now. */
+ if (FLOAT_MODE_P (compare_mode) && !FLOAT_MODE_P (result_mode))
+ return 0;
+
/* First, work out if the hardware can do this at all, or
if it's too slow.... */
if (!FLOAT_MODE_P (compare_mode))
Index: gcc/testsuite/gcc.target/powerpc/pr53487.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr53487.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr53487.c (revision 0)
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power7 -misel -ffast-math" } */
+
+struct phylo_s {
+ int left;
+};
+
+int Cluster(float **dmx, int N, struct phylo_s *tree)
+{
+ float **mx;
+ int *coord;
+ int i;
+ int Np;
+ int row, col;
+ float min;
+ for (col = 0; col < N; Np--)
+ {
+ for (row = 0; row < Np; row++)
+ for (col = row+1; col < Np; col++)
+ if (mx[row][col] < min)
+ i = row;
+ tree[Np-2].left = coord[i];
+ }
+ Free2DArray((void **) mx, N);
+}