------- 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