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

Reply via email to