Hi! As the testcase below shows (on i686-linux or x86_64-linux -m32), we don't unshare expressions in CALL_INSN_FUNCTION_USAGE, which with entry_value support now include MEMs. The invalid sharing then can lead to changes in unrelated insns affecting a call insn (or vice versa), which results in DF being out of date and ICE afterwards.
Fixed thusly, bootstrapped/regtested (with rtl checking) on x86_64-linux and i686-linux, ok for trunk? 2011-08-22 Jakub Jelinek <ja...@redhat.com> PR middle-end/48722 * emit-rtl.c (unshare_all_rtl_again): For CALL_INSNs, reset_used_flags also in CALL_INSN_FUNCTION_USAGE. (verify_rtl_sharing): Likewise and verify_rtx_sharing in there too. (unshare_all_rtl_in_chain): For CALL_INSNs copy_rtx_if_shared also CALL_INSN_FUNCTION_USAGE. * gcc.target/i386/pr48722.c: New test. --- gcc/emit-rtl.c.jj 2011-08-18 08:36:00.000000000 +0200 +++ gcc/emit-rtl.c 2011-08-22 08:48:27.000000000 +0200 @@ -2444,6 +2444,8 @@ unshare_all_rtl_again (rtx insn) { reset_used_flags (PATTERN (p)); reset_used_flags (REG_NOTES (p)); + if (CALL_P (p)) + reset_used_flags (CALL_INSN_FUNCTION_USAGE (p)); } /* Make sure that virtual stack slots are not shared. */ @@ -2610,6 +2612,8 @@ verify_rtl_sharing (void) { reset_used_flags (PATTERN (p)); reset_used_flags (REG_NOTES (p)); + if (CALL_P (p)) + reset_used_flags (CALL_INSN_FUNCTION_USAGE (p)); if (GET_CODE (PATTERN (p)) == SEQUENCE) { int i; @@ -2621,6 +2625,8 @@ verify_rtl_sharing (void) gcc_assert (INSN_P (q)); reset_used_flags (PATTERN (q)); reset_used_flags (REG_NOTES (q)); + if (CALL_P (q)) + reset_used_flags (CALL_INSN_FUNCTION_USAGE (q)); } } } @@ -2630,6 +2636,8 @@ verify_rtl_sharing (void) { verify_rtx_sharing (PATTERN (p), p); verify_rtx_sharing (REG_NOTES (p), p); + if (CALL_P (p)) + verify_rtx_sharing (CALL_INSN_FUNCTION_USAGE (p), p); } timevar_pop (TV_VERIFY_RTL_SHARING); @@ -2646,6 +2654,9 @@ unshare_all_rtl_in_chain (rtx insn) { PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn)); REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn)); + if (CALL_P (insn)) + CALL_INSN_FUNCTION_USAGE (insn) + = copy_rtx_if_shared (CALL_INSN_FUNCTION_USAGE (insn)); } } --- gcc/testsuite/gcc.target/i386/pr48722.c.jj 2011-08-22 08:53:10.000000000 +0200 +++ gcc/testsuite/gcc.target/i386/pr48722.c 2011-08-22 08:52:37.000000000 +0200 @@ -0,0 +1,13 @@ +/* PR middle-end/48722 */ +/* { dg-do compile } */ +/* { dg-options "-Os -mno-push-args" } */ + +extern long long a; +extern int b; +void bar (int, long long); + +void +foo (void) +{ + bar (a > 0x85, b); +} Jakub