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 <[email protected]>
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 <[email protected]>
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: [email protected], 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} } } */