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} } } */