https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127420

--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Haochen Jiang from comment #7)
> > What are typical cases?  Are they C++ programs?
> 
> All SPEC2026 cases are CXX + C or CXX. For SPEC2017, 511 is CXX + C, the
> remaining for mentioned is C only.
> 
> For 735, the case is a 20-case switch in a loop:
> 
>     c3c090:  inc    %rdx
>     c3c093:  mov    %ecx,(%rax)
>     c3c095:  movq   $0x0,0x8(%rax)
>     c3c09d:  cmp    %rsi,%rdx
>     c3c0a0:  jae    c3c118
>     c3c0a2:  cmp    $0x13,%edx
>     c3c0a5:  ja     c3c2ff
>     c3c0ab:  mov    %edx,%ecx
>     c3c0ad:  jmp    *0x1021900(,%rcx,8)       # 20-entry tablejump      <- 7
> bytes
>     c3c0b4:  nopl   0x0(%rax)
>     c3c0b8:  xor    %ecx,%ecx                 # <-- 932,626 hits land here
>     c3c0ba:  add    $0x10,%rax
>     c3c0be:  jmp    c3c090
> 
> The 84% c3c0ad indirect jmp FALLTHRU to c3c0b8, leading to total 26.7% for
> 735.

My patch only applies to sibcall, not table jump:

[hjl@gnu-zen4-1 pr127420]$ cat t.c
extern void bar0 (void);
extern void bar1 (void);
extern void bar2 (void);
extern void bar3 (void);
extern void bar4 (void);

void
foo (int i)
{
  switch (i)
    {
    case 0: bar0 (); break;
    case 1: bar1 (); break;
    case 2: bar2 (); break;
    case 3: bar3 (); break;
    case 4: bar4 (); break;
    }
}
[hjl@gnu-zen4-1 pr127420]$ make
/export/build/gnu/tools-build/gcc-gitlab-test-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-gitlab-test-debug/build-x86_64-linux/gcc/
-O2 -fno-plt -S t.c
[hjl@gnu-zen4-1 pr127420]$ cat t.s
        .file   "t.c"
        .text
        .p2align 4
        .globl  foo
        .type   foo, @function
foo:
.LFB0:
        .cfi_startproc
        cmpl    $4, %edi
        ja      .L1
        movl    %edi, %edi
        jmp     *.L4(,%rdi,8)
        .section        .rodata
        .align 8
        .align 4
.L4:
        .quad   .L8
        .quad   .L7
        .quad   .L6
        .quad   .L5
        .quad   .L3
        .text
        .p2align 4,,10
        .p2align 3
.L5:
        jmp     *bar3@GOTPCREL(%rip)
        ud2
        .p2align 4,,10
        .p2align 3
.L3:
        jmp     *bar4@GOTPCREL(%rip)
        ud2
        .p2align 4,,10
        .p2align 3
.L8:
        jmp     *bar0@GOTPCREL(%rip)
        ud2
        .p2align 4,,10
        .p2align 3
.L7:
        jmp     *bar1@GOTPCREL(%rip)
        ud2
        .p2align 4,,10
        .p2align 3
.L6:
        jmp     *bar2@GOTPCREL(%rip)
        ud2
.L1:
        ret
        .cfi_endproc
.LFE0:
        .size   foo, .-foo
        .ident  "GCC: (GNU) 17.0.0 20260918 (experimental)"
        .section        .note.GNU-stack,"",@progbits
[hjl@gnu-zen4-1 pr127420]$ 

Can you measure its performance impact?

Reply via email to