https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91213

            Bug ID: 91213
           Summary: Missed optimization: (sub X Y) -> (xor X Y) when Y <=
                    X and isPowerOf2(X + 1)
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nok.raven at gmail dot com
  Target Milestone: ---

Proof https://rise4fun.com/Alive/Xr3

unsigned foo(unsigned x)
{
    if (x > 31) __builtin_unreachable();
    return 31 - x;
}

unsigned bar(unsigned x)
{
    if (x > 63) __builtin_unreachable();
    return 63 - x;
}

The optimization seems to be manually applied to __builtin_clz, and because
GCC cannot reverse it or apply again the:

unsigned bsrl(unsigned x)
{
    return 31 - __builtin_clz(x);
}

becomes (sub 31 (xor 31 (bsr x))):

bsrl(unsigned int):
  bsrl %edi, %edi
  movl $31, %eax
  xorl $31, %edi
  subl %edi, %eax
  ret


https://godbolt.org/z/3nzi0z

Reply via email to