The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57459
The bug occurs in case of rare combination when insn uses inherited and original value, the pseudo is input and output and the pseudo value (as insn result) is unused.
The patch was successfully bootstrapped and tested on x86/x86-64. Committed as rev. 199762. 2013-06-06 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/57459 * lra-constraints.c (update_ebb_live_info): Fix typo for operand type when setting live regs. 2013-06-06 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/57459 * gcc.target/i386/pr57459.c: New test.
Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 199753) +++ lra-constraints.c (working copy) @@ -4545,7 +4545,7 @@ update_ebb_live_info (rtx head, rtx tail bitmap_clear_bit (&live_regs, reg->regno); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_IN + if (reg->type != OP_OUT && bitmap_bit_p (&check_only_regs, reg->regno)) bitmap_set_bit (&live_regs, reg->regno); /* It is quite important to remove dead move insns because it Index: testsuite/gcc.target/i386/pr57459.c =================================================================== --- testsuite/gcc.target/i386/pr57459.c (revision 0) +++ testsuite/gcc.target/i386/pr57459.c (working copy) @@ -0,0 +1,60 @@ +/* PR rtl-optimization/57459 */ +/* { dg-do run } */ +/* { dg-options "-fno-inline -O2 -minline-all-stringops -fno-omit-frame-pointer" } */ + +int total1[10], total2[10], total3[10], total4[10], total5[10], a[20]; +int len; + +void stackclean() { + void *ptr = __builtin_alloca(20000); + __builtin_memset(ptr, 0, 20000); +} + +void foo(const char *s) { + int r1 = a[1]; + int r2 = a[2]; + int r3 = a[3]; + int r4 = a[4]; + int r5 = a[5]; + + len = __builtin_strlen(s); + + if (s != 0) + return; + + while (r1) { + total1[r1] = r1; + r1--; + } + + while (r2) { + total2[r2] = r2; + r2--; + } + + while (r3) { + total3[r3] = r3; + r3--; + } + + while (r4) { + total4[r4] = r4; + r4--; + } + + while (r5) { + total5[r5] = r5; + r5--; + } +} + +extern void abort (void); + +int main() { + stackclean(); + foo("abcdefgh"); + if (len != 8) + abort (); + return 0; +} +