https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118279
Bug ID: 118279
Summary: gcc fails to eliminate unnecessary guards around
switch()
Product: gcc
Version: 14.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: arseny.kapoulkine at gmail dot com
Target Milestone: ---
When a switch is duplicated 4 times, gcc and clang "inline" the switch dispatch
for subsequent switches into the previous switch cases tail. This is correct
and expected. However, clang consistently uses a dispatch sequence without a
conditional branch; gcc does not guard the first switch dispatch, but does keep
unnecessary guards in subsequent switches.
Small example; the problem is visible at line 33 for gcc, where it emits:
cmp edx, 5
ja .L3
jmp [QWORD PTR .L11[0+rdx*8]]
vs clang that emits, at line 25:
movsxd r10, dword ptr [r8 + 4*r10]
add r10, r8
jmp r10
Note that clang's dispatch sequence uses an extra `add` because clang seems to
default to PIE; using `-fpie` for gcc produces equivalent code with the guard
retained as well:
cmp edx, 5
ja .L3
movsx rdx, DWORD PTR [r10+rdx*4]
add rdx, r10
jmp rdx
https://gcc.godbolt.org/z/P86shdno9