https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92903
Bug ID: 92903 Summary: Cannot elide byteswap when only needed to compare to multiple constants Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: jwerner at chromium dot org Target Milestone: --- I compiled the following test code on GCC 8.3.0: int test(int a) { const int swapped = __builtin_bswap32(a); if (swapped == 0x12345678 || swapped == 0x23456789) return 1; return 0; } On x86_64, I get: 0000000000000000 <test> (File Offset: 0x40): 0: 0f cf bswap %edi 2: 81 ff 78 56 34 12 cmp $0x12345678,%edi 8: 0f 94 c0 sete %al b: 81 ff 89 67 45 23 cmp $0x23456789,%edi 11: 0f 94 c2 sete %dl 14: 09 d0 or %edx,%eax 16: 0f b6 c0 movzbl %al,%eax 19: c3 retq And on aarch64, I get: 0000000000000000 <test> (File Offset: 0x40): 0: 528acf01 mov w1, #0x5678 // #22136 4: 5ac00800 rev w0, w0 8: 72a24681 movk w1, #0x1234, lsl #16 c: 6b01001f cmp w0, w1 10: 528cf121 mov w1, #0x6789 // #26505 14: 72a468a1 movk w1, #0x2345, lsl #16 18: 7a411004 ccmp w0, w1, #0x4, ne 1c: 1a9f17e0 cset w0, eq 20: d65f03c0 ret In both of those cases it would have been better to omit the byteswap instruction and instead embed the constants to compare to in their swapped form right away. This works correctly when comparing to a single constant, like this: int test(int a) { const int swapped = __builtin_bswap32(a); if (swapped == 0x12345678) return 1; return 0; } 0000000000000000 <test> (File Offset: 0x40): 0: 52868241 mov w1, #0x3412 // #13330 4: 72af0ac1 movk w1, #0x7856, lsl #16 8: 6b01001f cmp w0, w1 c: 1a9f17e0 cset w0, eq 10: d65f03c0 ret But comparing the swapped value to more than one constant somehow makes GCC miss this optimization, even if neither the swapped value nor the constants are used for anything else.