https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119683
Bug ID: 119683
Summary: [13/14 Regression] recalculating the return value
which was already in the register right before
function return
Product: gcc
Version: 13.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: nikola at radojevic dot rs
Target Milestone: ---
This C function demonstrates the regression, all of the examples are compiled
with just -O3:
unsigned ctoint(char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'z')
return c - 'a' + 10;
if (c >= 'A' && c <= 'Z')
return c - 'A' + 10;
return -1;
}
gcc 13.1 on godbolt generates the following code:
1 ctoint:
2 leal -48(%rdi), %eax
3 cmpb $9, %al
4 jbe .L7
5 leal -97(%rdi), %eax
6 cmpb $25, %al
7 jbe .L8
8 leal -65(%rdi), %edx
9 movsbl %dil, %eax
10 subl $55, %eax
11 cmpb $26, %dl
12 movl $-1, %edx
13 cmovnb %edx, %eax
14 ret
15 .L8:
16 movsbl %dil, %edi
17 leal -87(%rdi), %eax
18 ret
19 .L7:
20 movsbl %dil, %edi
21 leal -48(%rdi), %eax
22 ret
It calculates and stores the return value in %eax on line 2, and after a
compare and a jump, it recalculates the same exactly value on line 21.
For reference, gcc 12.4 on godbolt.org generates the following code, note that
it reuses the value that's already in the register on line 20:
1 ctoint:
2 leal -48(%rdi), %eax
3 cmpb $9, %al
4 jbe .L7
5 leal -97(%rdi), %eax
6 cmpb $25, %al
7 jbe .L8
8 leal -65(%rdi), %edx
9 leal -55(%rdi), %eax
10 cmpb $26, %dl
11 movsbl %al, %eax
12 movl $-1, %edx
13 cmovnb %edx, %eax
14 ret
15 .L8:
16 subl $87, %edi
17 movsbl %dil, %eax
18 ret
19 .L7:
20 movsbl %al, %eax
21 ret
Here's the godbolt link: https://c.godbolt.org/z/MK6v6f5Kj
I first noticed this issue on my distro's gcc 14:
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust
--enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib
--mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://gitea.artixlinux.org/packages/gcc/issues
--with-build-config=bootstrap-lto --with-linker-hash-style=gnu
--with-system-zlib --enable-__cxa_atexit --enable-cet=auto
--enable-checking=release --enable-clocale=gnu --enable-default-pie
--enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object
--enable-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.1 20250207 (GCC)