------- Comment #6 from ubizjak at gmail dot com 2010-03-14 20:59 ------- The problem is actually in loop2_invariant rtl pass, and -O1/-O2 difference is in fact due to missing cprop pass in -O1 case.
So, before _.162r.loop2_invariant, we have: 6 [`g_3']=0x1 7 r61:SI=[`l_5_5_2'] L13: 8 NOTE_INSN_BASIC_BLOCK 9 [`g_3']=r61:SI 11 {r60:SI=r61:SI+0x7;clobber flags:CC;} REG_DEAD: r63:SI REG_UNUSED: flags:CC REG_EQUAL: [`g_3']+0x7 12 [`g_3']=r60:SI and loop2_invariant pass declares (insn 11) as invariant even when REG_EQUAL says it depends on ['g_3']: 6 [`g_3']=0x1 7 r61:SI=[`l_5_5_2'] 11 {r63:SI=r61:SI+0x7;clobber flags:CC;} REG_DEAD: r62:SI REG_UNUSED: flags:CC REG_EQUAL: [`g_3']+0x7 L13: 8 NOTE_INSN_BASIC_BLOCK 9 [`g_3']=r61:SI 22 r60:SI=r63:SI 12 [`g_3']=r63:SI Things go down the hill from there, since later pass substitutes (insn 11) with REG_EQUAL value: [`g_3']+0x7 -> 0x1 + 0x7 = 0x8. So, the solution is to teach loop2_invariant to also look into REG_EQUAL notes if the insn is _really_ invariant or eventually clear REG_EQUAL notes when insn is moved out of the loop. Re-classified as rtl-optimization bug. -- ubizjak at gmail dot com changed: What |Removed |Added ---------------------------------------------------------------------------- Component|target |rtl-optimization http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43360