The second instance of a1+a2 is not PREed due to missing expression reassociation. int foo(int a1, int a2, int a3) { int b1,b2; b1 = a3 + a2 + a1; b2 = a1 + a2; return b1 + b2; }
Confirmed. Re-association generates D.1548_3 = a1_4(D) + a1_4(D); b1_5 = D.1548_3 + a2_2(D); b2_6 = b1_5 + a2_2(D); D.1549_7 = b2_6 + a3_1(D); but that does not expose SSA_NAMEs with the same value.
LLVM got it right: addl %esi, %edi leal (%rdx,%rdi,2), %eax vs gcc: addl %esi, %edx leal (%rsi,%rdi,2), %edi leal (%rdi,%rdx), %eax vs open64: leal 0(%rdi,%rsi,1), %eax # [0] addl %esi,%edx # [0] addl %edx,%edi # [1] addl %edi,%eax # [2] David
If we use -fwrapv, then GCC is able to get it. THere might be a dup of this bug already too.