Hello,

running the testsuite in powerpc64le-linux with --with-cpu=power7 causes
FAIL: tmpdir-g++.dg-struct-layout-1/t024 cp_compat_x_tst.o compile,  (internal 
compiler error)
due to an unrecognizable insn

(insn 137 136 138 5 (set (reg:V2DI 5 5)
        (vec_select:V2DI (reg:V2DI 211)
            (parallel [
                    (const_int 1 [0x1])
                    (const_int 0 [0])
                ]))) 
/home/gcc-build/gcc/testsuite/g++/g++.dg-struct-layout-1//t024_test.h:6 -1
     (nil))

i.e. an attempted vector permute into a GPR hard reg.  It turns out this happens
when rs6000_emit_le_vsx_move is called with a GPR hard reg destination, which
in turn can happen when passing vectors to a vararg routine.

However, rs6000_emit_le_vsx_move is not set up to handle GPRs.  Fortunately,
for GPRs this routine is not actually necessary; vectors can be loaded into
GPRs using the regular move patterns.

This patch fixes the problem by not invoking the rs6000_emit_le_vsx_move special
case if a hard reg GPR is involved as source/destination.

Tested on powerpc64le-linux.

OK for mainline?

Bye,
Ulrich


ChangeLog:

        * config/rs6000/vector.md ("mov<mode>"): Do not call
        rs6000_emit_le_vsx_move to move into or out of GPRs.
        * config/rs6000/rs6000.c (rs6000_emit_le_vsx_move): Assert
        source and destination are not GPR hard regs.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 205009)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -7947,6 +7947,7 @@
   gcc_assert (!BYTES_BIG_ENDIAN
              && VECTOR_MEM_VSX_P (mode)
              && mode != TImode
+             && !gpr_or_gpr_p (dest, source)
              && (MEM_P (source) ^ MEM_P (dest)));
 
   if (MEM_P (source))
Index: gcc/config/rs6000/vector.md
===================================================================
--- gcc/config/rs6000/vector.md (revision 205009)
+++ gcc/config/rs6000/vector.md (working copy)
@@ -108,6 +108,7 @@
   if (!BYTES_BIG_ENDIAN
       && VECTOR_MEM_VSX_P (<MODE>mode)
       && <MODE>mode != TImode
+      && !gpr_or_gpr_p (operands[0], operands[1])
       && (memory_operand (operands[0], <MODE>mode)
           ^ memory_operand (operands[1], <MODE>mode)))
     {
-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  ulrich.weig...@de.ibm.com

Reply via email to