[Bug target/88402] New: inefficient code generation for mask from CC

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug target/88402] New: inefficient code generation for mask from CC

msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88402

            Bug ID: 88402
           Summary: inefficient code generation for mask from CC
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

For sth like

unsigned long foo (int a, int b)
{
  return a < b ? -1ul : 0;
}

we produce at -O[23]

        xorl    %eax, %eax
        cmpl    %esi, %edi
        setl    %al
        negq    %rax
        ret

(partial register stall?)

and at -O

        cmpl    %esi, %edi
        setl    %al
        movzbl  %al, %eax
        negq    %rax

while we could use sbbq %rax, %rax if the suggestion at
https://lwn.net/Articles/744257/ is correct.
Reply | Threaded
Open this post in threaded view
|

[Bug target/88402] inefficient code generation for mask from CC

msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88402

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I don't think you can use it in that case, you get it with:
unsigned long bar (unsigned int a, unsigned int b)
{
  return a < b ? -1ul : 0;
}
which does something different:
        cmpl    %esi, %edi
        sbbq    %rax, %rax
        ret
at -O2 as well as -O.
Reply | Threaded
Open this post in threaded view
|

[Bug target/88402] inefficient code generation for mask from CC

msebor at gcc dot gnu.org
In reply to this post by msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88402

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amonakov at gcc dot gnu.org

--- Comment #2 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
It's possible to change signed comparison to unsigned by rotating integer
domain by half, i.e.

  foo(a, b) == bar(a^0x80000000, b^0x80000000)

but this increases register pressure if a and b are not dead after the
comparison.
Reply | Threaded
Open this post in threaded view
|

[Bug target/88402] inefficient code generation for mask from CC

msebor at gcc dot gnu.org
In reply to this post by msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88402

--- Comment #3 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
However, this may be worthwhile when one of operands is an immediate, as in
that case there's no register pressure increase, and the xor just mutates the
immediate.

Essentially, we'd change e.g.

  (signed)a < 0xabcd ? -1ul : 0

to

  (a^0x80000000) < 0x8000abcd ? -1ul : 0

and emit a xorl/cmpl/sbbq sequence, plus a mov if a remains live.

Not for 64-bit operands though, where the 64-bits immediates would be costly.

But unfortunately today we don't manage to use the cmp-sbb trick for unsigned
comparison against an immediate, i.e. for

unsigned long baz (unsigned int a)
{
  return a < 123 ? -1ul : 0;
}

we emit

        xorl    %eax, %eax
        cmpl    $122, %edi
        setbe   %al
        negq    %rax
Reply | Threaded
Open this post in threaded view
|

[Bug target/88402] inefficient code generation for mask from CC

msebor at gcc dot gnu.org
In reply to this post by msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88402

--- Comment #4 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
(In reply to Alexander Monakov from comment #3)
> But unfortunately today we don't manage to use the cmp-sbb trick for
> unsigned comparison against an immediate, i.e. for
>
> unsigned long baz (unsigned int a)
> {
>   return a < 123 ? -1ul : 0;
> }

It's probably more appropriate to discuss this aspect separately: PR 88425.