This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Fix ICE when loading vectors into GPRs in little-endian


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.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]