https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91965
Bug ID: 91965
Summary: missing simplification for (C - a) << N
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: amonakov at gcc dot gnu.org
Target Milestone: ---
Noticed this issue when preparing a testcase for PR 87047. We do not simplify
(1048575ull - x) << 44 on GIMPLE:
unsigned long long foo(unsigned long long a)
{
return (1048575 - a) << 44;
}
void bar(unsigned long long *a)
{
for (int i = 0; i < 1024; i++)
a[i] = foo(a[i]);
}
we use (~a)<<44 for 'foo', but that is thanks to combine, in 'bar' combine
doesn't make the same transform (the 1048575 constant is moved into a pseudo in
another BB, and combine doesn't know that's the only use):
foo:
movq %rdi, %rax
notq %rax
salq $44, %rax
ret
bar:
leaq 8192(%rdi), %rcx
movl $1048575, %edx
.L4:
movq %rdx, %rax
subq (%rdi), %rax
addq $8, %rdi
salq $44, %rax
movq %rax, -8(%rdi)
cmpq %rcx, %rdi
jne .L4
ret
Do we want to handle this early on via match.pd? Perhaps also applies to
simplifying (a +- C) << N.