On Fri, Dec 01, 2017 at 05:33:39PM -0600, Segher Boessenkool wrote:
> Okay for trunk.  Further improvements welcome ;-)  Thanks!

Here is the patch for GCC 7 (the bug shows up in GCC 7).  It is slightly
different due to the surrounding lines in rs6000.c being different.  Is it ok
to apply?  There were no regressions in the build.

This patch will not be needed in GCC 6.

[gcc]
2017-12-04  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        Back port from trunk
        2017-12-01  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/81959
        * config/rs6000/rs6000.c (rs6000_address_for_fpconvert): Check for
        whether we can allocate pseudos before trying to fix an address.
        * config/rs6000/rs6000.md (float_<mode>si2_hw): Make sure the
        memory address is indexed or indirect.
        (floatuns_<mode>si2_hw2): Likewise.

[gcct/testsuite]
2017-12-04  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        Back port from trunk
        2017-12-01  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/81959
        * gcc.target/powerpc/pr81959.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 255341)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -39938,7 +39938,8 @@ rs6000_address_for_fpconvert (rtx x)
 
   gcc_assert (MEM_P (x));
   addr = XEXP (x, 0);
-  if (! legitimate_indirect_address_p (addr, strict_p)
+  if (can_create_pseudo_p ()
+      && ! legitimate_indirect_address_p (addr, strict_p)
       && ! legitimate_indexed_address_p (addr, strict_p))
     {
       if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 255341)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -14642,6 +14642,9 @@ (define_insn_and_split "float_<mode>si2_
 {
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (DImode);
+
+  if (MEM_P (operands[1]))
+    operands[1] = rs6000_address_for_fpconvert (operands[1]);
 })
 
 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
@@ -14705,6 +14708,9 @@ (define_insn_and_split "floatuns_<mode>s
 {
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (DImode);
+
+  if (MEM_P (operands[1]))
+    operands[1] = rs6000_address_for_fpconvert (operands[1]);
 })
 
 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
Index: gcc/testsuite/gcc.target/powerpc/pr81959.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr81959.c  (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr81959.c  (working copy)
@@ -0,0 +1,25 @@
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -mfloat128" } */
+
+/* PR 81959, the compiler raised on unrecognizable insn message in converting
+   int to __float128, where the int had a PRE_INC in the address.  */
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE 1024
+#endif
+
+void
+convert_int_to_float128 (__float128 * __restrict__ p,
+                        int * __restrict__ q)
+{
+  unsigned long i;
+
+  for (i = 0; i < ARRAY_SIZE; i++)
+    p[i] = (__float128)q[i];
+}
+
+/* { dg-final { scan-assembler     {\mlfiwax\M|\mlxsiwax\M} } } */
+/* { dg-final { scan-assembler     {\mxscvsdqp\M}           } } */
+/* { dg-final { scan-assembler-not {\mmtvsrd\M}             } } */
+/* { dg-final { scan-assembler-not {\mmtvsrw[sz]\M}         } } */

Reply via email to