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_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 "float2" @@ -14705,6 +14708,9 @@ (define_insn_and_split "floatuns_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 "floatuns2" 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} } } */