https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96685
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Though, there is some canonicalization problem GENERIC vs. GIMPLE: unsigned f1 (unsigned x, unsigned y) { unsigned int r = (x - y); return ~r; } unsigned f2 (unsigned x, unsigned y) { unsigned int r = ~(x - y); return r; } unsigned f3 (unsigned x) { unsigned int r = (x - 23); return ~r; } unsigned f4 (unsigned x) { unsigned int r = ~(x - 23); return r; } int f5 (int x, int y) { int r = (x - y); return ~r; } int f6 (int x, int y) { int r = ~(x - y); return r; } int f7 (int x) { int r = (x - 23); return ~r; } int f8 (int x) { int r = ~(x - 23); return r; } Before the above patch, the above testcase emitted: subl %esi, %edi movl %edi, %eax notl %eax for f1/f2/f5/f6 and leal -23(%rdi), %eax notl %eax for f3/f4/f7/f8. With the patch it emits: notl %edi leal (%rdi,%rsi), %eax for f1/f5/f6, subl %edi, %esi leal -1(%rsi), %eax for f2, notl %edi leal 23(%rdi), %eax for f3/f7, movl $22, %eax subl %edi, %eax for f4/f8.