https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85758
Bug ID: 85758 Summary: questionable bitwise folding (missing single use check?) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: amonakov at gcc dot gnu.org Target Milestone: --- The following should be translated as-is: void f(int a, int b); void g(int a, int b, int m, int s) { m &= s; a += m; m ^= s; b += m; f(a, b); } However instead of and/add/xor/add we get mov/not/and/and/add/add: movl %edx, %eax notl %edx andl %ecx, %eax andl %edx, %ecx addl %eax, %edi addl %ecx, %esi jmp f This is because forwprop applies an identity to m = (m & s) ^ s: g (int a, int b, int m, int s) { <bb 2> : m_3 = m_1(D) & s_2(D); a_5 = a_4(D) + m_3; m_6 = m_3 ^ s_2(D); b_8 = b_7(D) + m_6; f (a_5, b_8); return; } gimple_simplified to _11 = ~m_1(D); m_6 = s_2(D) & _11; g (int a, int b, int m, int s) { int _11; <bb 2> : m_3 = m_1(D) & s_2(D); a_5 = m_3 + a_4(D); _11 = ~m_1(D); m_6 = s_2(D) & _11; b_8 = m_6 + b_7(D); f (a_5, b_8); return; } However since m_3 is used, this is more costly. Shouldn't this folding check for single use of the intermediate expr? From a quick look, this is probably match.pd:/* Fold (X & Y) ^ Y and (X ^ Y) & Y as ~X & Y. */