From: Vladimir Makarov Date: Tue, 20 Oct 2015 16:26:05 +0000 (+0000) Subject: re PR rtl-optimization/67609 (Generates wrong code for SSE2 _mm_load_pd) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8cda1c3eb263349536beb300cf6c278f51f2fead;p=gcc.git re PR rtl-optimization/67609 (Generates wrong code for SSE2 _mm_load_pd) 2015-10-20 Vladimir Makarov PR rtl-optimization/67609 * lra-splill.c (lra_final_code_change): Don't remove all sub-registers. 2015-10-20 Vladimir Makarov PR rtl-optimization/67609 * gcc.target/i386/pr67609.c: New. From-SVN: r229087 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3398170ed4..9ad52a8262e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-10-20 Vladimir Makarov + + PR rtl-optimization/67609 + * lra-splill.c (lra_final_code_change): Don't remove all + sub-registers. + 2015-10-20 Kyrylo Tkachov * simplify-rtx.c (simplify_binary_operation): If either operand was diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index a210c41da31..9c1207f5057 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -727,14 +727,44 @@ lra_final_code_change (void) lra_insn_recog_data_t id = lra_get_insn_recog_data (insn); 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) - && 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) + 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; + } + } if (insn_change_p) lra_update_operator_dups (id); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b6118fd8a3..8620128cdff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-20 Vladimir Makarov + + PR rtl-optimization/67609 + * gcc.target/i386/pr67609.c: New. + 2015-10-20 Kyrylo Tkachov * gcc.target/aarch64/fmul_fcvt_1.c: Add multiply-by-32 cases. diff --git a/gcc/testsuite/gcc.target/i386/pr67609.c b/gcc/testsuite/gcc.target/i386/pr67609.c new file mode 100644 index 00000000000..518071bdd86 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr67609.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-final { scan-assembler "movdqa" } } */ + +#include +__m128d reg; +void set_lower(double b) +{ + double v[2]; + _mm_store_pd(v, reg); + v[0] = b; + reg = _mm_load_pd(v); +}