When I added the optimization for loading 32-bit values directly into the
vector registers from memory to convert to IEEE 128-bit floating point, I
forgot to make sure the address did not have PRE_INCREMENT, etc. addressing.

I checked the compiler on a little endian power8 system.  Is it ok to check
this patch into the trunk and back port it GCC 7?  GCC 6 did not have the
optimization.

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

        PR target/81959
        * config/rs6000/rs6000.md (float_<mode>si2_hw): If register
        allocation hasn't been done, make sure the memory address is
        X-FORM (register+register).
        (floatuns_<mode>si2_hw2): Likewise.

[gcct/testsuite]
2017-08-28  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.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 251358)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -14505,6 +14505,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]) && !reload_completed)
+    operands[1] = rs6000_address_for_fpconvert (operands[1]);
 })
 
 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
@@ -14568,6 +14571,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]) && !reload_completed)
+    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  (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr81959.c  (revision 0)
@@ -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