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.

Reply via email to