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).