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)