https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122943
Bug ID: 122943
Summary: [14/15 Regression] Wrong code for switch on int64_t on
32-bit ARM at -O2
Product: gcc
Version: 14.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: baltth at gmail dot com
Target Milestone: ---
Created attachment 62960
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62960&action=edit
Preprocessed source of a function generating incorrect code with -O2
When compiling a switch statement on int64_t for 32-bit ARM with -O2,
GCC 14.2.0 may generate incorrect code that only compares the low 32 bits
(r0), ignoring the high 32 bits (r1).
Sample code:
```
unsigned char arm_switch_o2_bug(long long val) {
unsigned char result = 0;
switch (val) {
case 0: result = 1; break; /* val == INT64_MIN passes this label */
case 1: result = 2; break;
case 2: result = 3; break;
default: break;
}
return result;
}
```
Compiled with arm-linux-gnueabi-gcc-14 -march=armv7ve -mthumb -O2 -S
./arm_switch_o2_bug.c
The generated assembly is
```
arm_switch_o2_bug:
cmp r0, #2
itte ls
addls r0, r0, #1
uxtbls r0, r0
movhi r0, #0
bx lr
```
Here r1 is ignored completely, causing all input values with
lower word value 0-2 mapped incorrectly.
arm-gcc 14.x and 15.x versions generate wrong code
(https://godbolt.org/z/do6bzsf6x)
arm-gcc version 13.x generates correct code,
adding an sbcs r1, r1, #0 instruction after cmp r0, #2
(https://godbolt.org/z/obrrcKv7a)
Conditions to trigger wrong code generation:
- use Thumb instructions on a 32 bit architecture
- use -O2
- create a switch
- with condition type long long (or an enumeration with
the same underlying type),
- mapping sequence-to-sequence (e.g. 1,2,3 to 5,6,7),
- having three or more case labels
Output of arm-linux-gnueabi-gcc-14 -v:
```
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabi-gcc-14
COLLECT_LTO_WRAPPER=/usr/libexec/gcc-cross/arm-linux-gnueabi/14/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
14.2.0-4ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-14/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr
--with-gcc-major-version-only --program-suffix=-14 --enable-shared
--enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace
--enable-gnu-unique-object --disable-libitm --disable-libquadmath
--disable-libquadmath-support --enable-plugin --with-system-zlib
--enable-libphobos-checking=release --without-target-system-zlib
--enable-multiarch --disable-sjlj-exceptions
--with-specs='%{mfloat-abi=hard:-march=armv7-a -mcpu=generic-armv7-a
-mfloat-abi=hard}' --with-arch=armv5t --with-float=soft --disable-werror
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi-
--includedir=/usr/arm-linux-gnueabi/include
--with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (Ubuntu 14.2.0-4ubuntu2~24.04)
```