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.