diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2450e4fca91..48fdab630fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-01-29 H.J. Lu + + PR target/69530 + * lra-splill.c (lra_final_code_change): Revert r229087 by + removing all sub-registers. + 2016-01-29 Steve Ellcey PR target/65604 diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index fa0a579d74c..5709ef13e8d 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -760,44 +760,14 @@ lra_final_code_change (void) struct lra_static_insn_data *static_id = id->insn_static_data; bool insn_change_p = false; - - for (i = id->insn_static_data->n_operands - 1; i >= 0; i--) - { - if (! DEBUG_INSN_P (insn) && static_id->operand[i].is_operator) - continue; - - rtx op = *id->operand_loc[i]; - - if (static_id->operand[i].type == OP_OUT - && GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)) - && ! LRA_SUBREG_P (op)) - { - hard_regno = REGNO (SUBREG_REG (op)); - /* We can not always remove sub-registers of - hard-registers as we may lose information that - only a part of registers is changed and - subsequent optimizations may do wrong - transformations (e.g. dead code eliminations). - We can not also keep all sub-registers as the - subsequent optimizations can not handle all such - cases. Here is a compromise which works. */ - if ((GET_MODE_SIZE (GET_MODE (op)) - < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) - && (hard_regno_nregs[hard_regno][GET_MODE (SUBREG_REG (op))] - == hard_regno_nregs[hard_regno][GET_MODE (op)]) -#ifdef STACK_REGS - && (hard_regno < FIRST_STACK_REG - || hard_regno > LAST_STACK_REG) -#endif - ) - continue; - } - if (alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn))) - { - lra_update_dup (id, i); - insn_change_p = true; - } - } + + for (i = id->insn_static_data->n_operands - 1; i >= 0; i--) + if ((DEBUG_INSN_P (insn) || ! static_id->operand[i].is_operator) + && alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn))) + { + lra_update_dup (id, i); + insn_change_p = true; + } if (insn_change_p) lra_update_operator_dups (id); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d6b8d877a6..4d8fa237895 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-29 H.J. Lu + + PR target/69530 + * gcc.target/i386/pr69530.c: New test. + 2016-01-29 Steve Ellcey PR target/65604 diff --git a/gcc/testsuite/gcc.target/i386/pr69530.c b/gcc/testsuite/gcc.target/i386/pr69530.c new file mode 100644 index 00000000000..9146d1daf53 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr69530.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O -fno-forward-propagate -fno-split-wide-types -mavx " } */ + +typedef unsigned __int128 v32u128 __attribute__ ((vector_size (32))); + +v32u128 +foo (v32u128 v32u128_0) +{ + v32u128_0[0] *= v32u128_0[1]; + return v32u128_0; +}