This is a regression with -O2 -fno-strict-overflow present on the 4.5 branch. The compiler generates wrong code because of a problematic transformation done by if-convert. REG_EQUAL notes aren't taken into account to compute liveness info so when insns are moved above a conditional branch in the transformation (2) if (test) goto E; // x not live x = big(); goto L; E: x = b; goto M; becomes x = b; if (test) goto M; x = big(); goto L; they can change the reaching def of a REG_EQUAL note referring to x in the big() part. A related problem was fixed by Joern in PR rtl-opt/21767, but this was for the REG_EQUAL notes attached to the insns being moved. Fixed by removing the REG_EQUAL notes referring to registers set in the insns being moved; these registers are already computed during the transformation. The patch also fixes inconsistencies in the dumping routines of DF, where uses in REG_EQUAL notes were sometimes printed as 'e' and sometimes as 'u'; they should now be printed as 'e' by all routines. Tested on {x86_64,i586}-suse-linux, applied on the mainline and 4.5 branch. 2010-11-16 Eric Botcazou PR rtl-optimization/46315 * rtl.h (remove_reg_equal_equiv_notes_for_regno): Declare. * rtlanal.c (remove_reg_equal_equiv_notes_for_regno): New function extracted from... * dce.c (delete_corresponding_reg_eq_notes): ...here. Rename into... (remove_reg_equal_equiv_notes_for_defs): ...this. (delete_unmarked_insns): Adjust to above renaming. * ifcvt.c (dead_or_predicable): Remove REG_EQUAL and REG_EQUIV notes referring to registers set in the insns being moved, if any. * df-core.c (df_ref_dump): New function extracted from... (df_refs_chain_dump): ...here. Call it. (df_regs_chain_dump): Likewise. * df-problems.c (df_chain_dump): Print 'e' for uses in notes. * df-scan.c (df_scan_start_dump): Likewise. Fix long line. 2010-11-16 Eric Botcazou * gcc.dg/pr46315.c: New test. -- Eric Botcazou