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

            Bug ID: 128114
           Summary: [16/17 Regression] aarch64 -Os: c ? a & K : a uses
                    csel instead of cbz, one instruction larger
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yuki.tanaka at defaultcase dot de
  Target Milestone: ---

int a (int a, int c) { return c ? (a & 0xf0) : a; }
int b (int a, int c) { if (c == 0) a &= 7; return a; }

At -Os GCC 16.1 emits one insn more for both functions than GCC 15.2
(16 instead of 12 bytes each). -fno-if-conversion gives the 15.2 code
again.

Compiler Explorer, -Os (GCC 15.2 vs. GCC 16.1):

ARM64 GCC 15.2 (same since at least GCC 7.3.0):
a:
        cbz     w1, .L2
        and     w0, w0, 240
.L2:
        ret
b:
        cbnz    w1, .L7
        and     w0, w0, 7
.L7:
        ret

ARM64 GCC 16.1:
a:
        and     w2, w0, 240
        cmp     w1, 0
        csel    w0, w2, w0, ne
        ret
b:
        and     w2, w0, 7
        cmp     w1, 0
        csel    w0, w2, w0, eq
        ret

The same happens when & K is replaced by | K, ^ K, + K (except + 1),
- K, << K or + b: one instruction more in each case. GCC 17 is also larger
than 15.2 here (5 instruction, see PR128113).

Reply via email to