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

            Bug ID: 108938
           Summary: Missing bswap detection
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: crazylht at gmail dot com
  Target Milestone: ---

This is the x86 version of this bug.


+++ This bug was initially created as a clone of Bug #108874 +++


If we look at the arm testcases in gcc.target/arm/rev16.c
typedef unsigned int __u32;

__u32
__rev16_32_alt (__u32 x)
{
  return (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)
         | (((__u32)(x) & (__u32)0x00ff00ffUL) << 8);
}

__u32
__rev16_32 (__u32 x)
{
  return (((__u32)(x) & (__u32)0x00ff00ffUL) << 8)
         | (((__u32)(x) & (__u32)0xff00ff00UL) >> 8);
}

we should be able to generate bswap instructions for x86

GCC fails to do so and generates:
__rev16_32_alt(unsigned int):
        mov     eax, edi
        sal     edi, 8
        shr     eax, 8
        and     edi, -16711936
        and     eax, 16711935
        or      eax, edi
        ret
__rev16_32(unsigned int):
        mov     eax, edi
        shr     edi, 8
        sal     eax, 8
        and     edi, 16711935
        and     eax, -16711936
        or      eax, edi
        ret

whereas clang manages to recognise it all into:

__rev16_32_alt(unsigned int):                    # @__rev16_32_alt(unsigned
int)
        mov     eax, edi
        bswap   eax
        ror     eax, 16
        ret
__rev16_32(unsigned int):                        # @__rev16_32(unsigned int)
        mov     eax, edi
        bswap   eax
        ror     eax, 16
        ret

Reply via email to