diff mbox

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

Message ID 201311191503.rAJF3lX3024031@d06av02.portsmouth.uk.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Nov. 19, 2013, 3:03 p.m. UTC
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.

Comments

David Edelsohn Nov. 19, 2013, 3:06 p.m. UTC | #1
On Tue, Nov 19, 2013 at 10:03 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> 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.

Okay.

Thanks, David
diff mbox

Patch

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)))
     {