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

--- Comment #9 from Haochen Jiang <haochen.jiang at intel dot com> ---
(In reply to H.J. Lu from comment #8)
> (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?

I am currently mearsuring on EMR.

Reply via email to