The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63491
The patch was bootstrapped on x86-64, power64, and aarch64. Committed as rev. 221552. 2015-03-19 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/63491 * lra-constraints.c (check_and_process_move): Use src instead of sreg. Remove some dead code. 2015-03-19 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/63491 * gcc.target/powerpc/pr63491.c: New.
Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 221494) +++ lra-constraints.c (working copy) @@ -1074,10 +1074,9 @@ static bool check_and_process_move (bool *change_p, bool *sec_mem_p ATTRIBUTE_UNUSED) { int sregno, dregno; - rtx dest, src, dreg, sreg, old_sreg, new_reg, scratch_reg; + rtx dest, src, dreg, sreg, new_reg, scratch_reg; rtx_insn *before; enum reg_class dclass, sclass, secondary_class; - machine_mode sreg_mode; secondary_reload_info sri; lra_assert (curr_insn_set != NULL_RTX); @@ -1101,8 +1100,6 @@ check_and_process_move (bool *change_p, were a right class for the pseudo, secondary_... hooks usually are not define for ALL_REGS. */ return false; - sreg_mode = GET_MODE (sreg); - old_sreg = sreg; if (REG_P (sreg)) sclass = get_reg_class (REGNO (sreg)); if (sclass == ALL_REGS) @@ -1161,9 +1158,9 @@ check_and_process_move (bool *change_p, sri.icode = CODE_FOR_nothing; sri.extra_cost = 0; secondary_class - = (enum reg_class) targetm.secondary_reload (true, sreg, + = (enum reg_class) targetm.secondary_reload (true, src, (reg_class_t) dclass, - sreg_mode, &sri); + GET_MODE (src), &sri); /* Check the target hook consistency. */ lra_assert ((secondary_class == NO_REGS && sri.icode == CODE_FOR_nothing) @@ -1179,14 +1176,12 @@ check_and_process_move (bool *change_p, *change_p = true; new_reg = NULL_RTX; if (secondary_class != NO_REGS) - new_reg = lra_create_new_reg_with_unique_value (sreg_mode, NULL_RTX, + new_reg = lra_create_new_reg_with_unique_value (GET_MODE (src), NULL_RTX, secondary_class, "secondary"); start_sequence (); - if (old_sreg != sreg) - sreg = copy_rtx (sreg); if (sri.icode == CODE_FOR_nothing) - lra_emit_move (new_reg, sreg); + lra_emit_move (new_reg, src); else { enum reg_class scratch_class; @@ -1197,18 +1192,13 @@ check_and_process_move (bool *change_p, (insn_data[sri.icode].operand[2].mode, NULL_RTX, scratch_class, "scratch")); emit_insn (GEN_FCN (sri.icode) (new_reg != NULL_RTX ? new_reg : dest, - sreg, scratch_reg)); + src, scratch_reg)); } before = get_insns (); end_sequence (); lra_process_new_insns (curr_insn, before, NULL, "Inserting the move"); if (new_reg != NULL_RTX) - { - if (GET_CODE (src) == SUBREG) - SUBREG_REG (src) = new_reg; - else - SET_SRC (curr_insn_set) = new_reg; - } + SET_SRC (curr_insn_set) = new_reg; else { if (lra_dump_file != NULL) Index: testsuite/gcc.target/powerpc/pr63491.c =================================================================== --- testsuite/gcc.target/powerpc/pr63491.c (revision 0) +++ testsuite/gcc.target/powerpc/pr63491.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-options "-O1 -m64 -mcpu=power8 -mlra" } */ + +typedef __int128_t __attribute__((__vector_size__(16))) vector_128_t; +typedef unsigned long long scalar_64_t; + +vector_128_t +foo (void) +{ + union { + scalar_64_t i64[2]; + vector_128_t v128; + } u; + u.i64[0] = 1; + u.i64[1] = 2; + return u.v128; +}