https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128388
Bug ID: 128388
Summary: i386: -mindirect-branch-cs-prefix omits CS prefix on
calls to APX r16-r31 indirect thunks (REX_INT_REGNO_P
tested twice)
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: x86_64-*-*
Reproducer
----------
$ cat trigger.c
extern void (*fptr) (void);
void foo (void) /* tail call: jmp site, gets "cs" */
{
fptr ();
}
int bar (void) /* normal call: call site, loses "cs" for %r16 */
{
fptr ();
return 0;
}
Compile flag: x86_64-linux-gnu-gcc -O2 -mapxf -fno-pic
-mindirect-branch=thunk-extern -mindirect-branch-cs-prefix
-ffixed-{rax,rbx,rcx,rdx,rsi,rdi,rbp,r8..r15} -S trigger.c
foo:
movq fptr(%rip), %r16
cs # tail call: prefix present
jmp __x86_indirect_thunk_r16
bar:
subq $8, %rsp
movq fptr(%rip), %r16
call __x86_indirect_thunk_r16 # normal call: CS prefix missing
xorl %eax, %eax
Root cause
----------
gcc/config/i386/i386.cc:17465 in ix86_output_indirect_branch_via_reg:
if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
&& ix86_indirect_branch_cs_prefix)
fprintf (asm_out_file, "\tcs\n");
The same test in ix86_output_jmp_thunk_or_indirect (i386.cc:17413) uses
REX_INT_REGNO_P || REX2_INT_REGNO_P, so only the call form misses the APX
EGPRs. -ffixed-* is only used to force the call target into %r16; GCC
trunk (Compiler Explorer, 2026-11-01) emits the same bare call.
Suggested Fix
-------------
- if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
+ if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))