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); +}