The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58759
The patch was successfully bootstrapped and tested on x86/x86-64. Committed as rev. 204080. 2013-10-25 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/58759 * lra-constraints.c (lra_constraints): Remove wrong condition to remove insn setting up an equivalent pseudo. 2013-10-25 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/58759 * gcc.target/i386/pr58759.c: New.
Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 204069) +++ lra-constraints.c (working copy) @@ -3975,18 +3975,6 @@ lra_constraints (bool first_p) dest_reg = SUBREG_REG (dest_reg); if ((REG_P (dest_reg) && (x = get_equiv_substitution (dest_reg)) != dest_reg - /* Check that this is actually an insn setting up - the equivalence. */ - && (in_list_p (curr_insn, - ira_reg_equiv - [REGNO (dest_reg)].init_insns) - /* Init insns may contain not all insns setting - up equivalence as we have live range - splitting. So here we use another condition - to check insn setting up the equivalence - which should be removed, e.g. in case when - the equivalence is a constant. */ - || ! MEM_P (x)) /* Remove insns which set up a pseudo whose value can not be changed. Such insns might be not in init_insns because we don't update equiv data @@ -3999,8 +3987,10 @@ lra_constraints (bool first_p) secondary memory movement. Then the pseudo is spilled and we use the equiv constant. In this case we should remove the additional insn and - this insn is not init_insns list. */ + this insn is not init_insns list. */ && (! MEM_P (x) || MEM_READONLY_P (x) + /* Check that this is actually an insn setting + up the equivalence. */ || in_list_p (curr_insn, ira_reg_equiv [REGNO (dest_reg)].init_insns))) Index: testsuite/gcc.target/i386/pr58759.c =================================================================== --- testsuite/gcc.target/i386/pr58759.c (revision 0) +++ testsuite/gcc.target/i386/pr58759.c (working copy) @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + + +int a, b, c, d, e, f, h, l, m, n, k, o; +long long g; + +struct S +{ + int f1; + int f2; + int f3; + int f4; +}; + +static struct S i = {0,0,0,0}, j; + +void +foo () +{ + m = 1 & d; + n = b + c; + o = k >> 1; + f = 0 == e; +} + +int +main () +{ + for (; h < 1; h++) + { + g = 1 | (0 > 1 - a ? 0 : a); + foo (); + for (l = 0; l < 3; l++) + j = i; + } + return 0; +}