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  <meiss...@linux.vnet.ibm.com>

        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  <meiss...@linux.vnet.ibm.com>

        * gcc.target/powerpc/pr53487.c: New test.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     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);
+}

Reply via email to