From Voluminous Lemur, 1 Week ago, written in Plain Text.
This paste will check out in 2 Weeks.
Embed
  1. This c function demonstrates the regression, all of the examples are compiled with just -O3:
  2.   1 unsigned ctoint(char c) {
  3.   2     if (c >= '0' && c <= '9')
  4.   3         return c - '0';
  5.   4
  6.   5     if (c >= 'a' && c <= 'z')
  7.   6         return c - 'a' + 10;
  8.   7
  9.   8     if (c >= 'A' && c <= 'Z')
  10.   9         return c - 'A' + 10;
  11.  10
  12.  11     return -1;
  13.  12 }
  14.  
  15. gcc 13.1 on godbolt generates the following code:
  16.   1 ctoint:
  17.   2         leal    -48(%rdi), %eax
  18.   3         cmpb    $9, %al
  19.   4         jbe     .L7
  20.   5         leal    -97(%rdi), %eax
  21.   6         cmpb    $25, %al
  22.   7         jbe     .L8
  23.   8         leal    -65(%rdi), %edx
  24.   9         movsbl  %dil, %eax
  25.  10         subl    $55, %eax
  26.  11         cmpb    $26, %dl
  27.  12         movl    $-1, %edx
  28.  13         cmovnb  %edx, %eax
  29.  14         ret
  30.  15 .L8:
  31.  16         movsbl  %dil, %edi
  32.  17         leal    -87(%rdi), %eax
  33.  18         ret
  34.  19 .L7:
  35.  20         movsbl  %dil, %edi
  36.  21         leal    -48(%rdi), %eax
  37.  22         ret
  38.  
  39. 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.
  40.  
  41. For reference, gcc 12.4 on  generates the following code, note that it reuses the value that's already in the register on line 20:
  42.   1 ctoint:
  43.   2         leal    -48(%rdi), %eax
  44.   3         cmpb    $9, %al
  45.   4         jbe     .L7
  46.   5         leal    -97(%rdi), %eax
  47.   6         cmpb    $25, %al
  48.   7         jbe     .L8
  49.   8         leal    -65(%rdi), %edx
  50.   9         leal    -55(%rdi), %eax
  51.  10         cmpb    $26, %dl
  52.  11         movsbl  %al, %eax
  53.  12         movl    $-1, %edx
  54.  13         cmovnb  %edx, %eax
  55.  14         ret
  56.  15 .L8:
  57.  16         subl    $87, %edi
  58.  17         movsbl  %dil, %eax
  59.  18         ret
  60.  19 .L7:
  61.  20         movsbl  %al, %eax
  62.  21         ret
  63.  
  64. Here's the godbolt link:
  65. I first noticed this issue on my distro's gcc 14:
  66. $ gcc -v
  67. Using built-in specs.
  68. COLLECT_GCC=gcc
  69. COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper
  70. Target: x86_64-pc-linux-gnu
  71. 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= --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
  72. Thread model: posix
  73. Supported LTO compression algorithms: zlib zstd
  74. gcc version 14.2.1 20250207 (GCC)
  75.  
captcha