https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97469
Bug ID: 97469 Summary: __attribute__ ((__target__ ("..."))) resets -mcmodel= values, breaks grub compilation Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: slyfox at gcc dot gnu.org Target Milestone: --- Bug initially observed as a build failure on grub-2.04. There 32-bit PLT relocations get generated against external unresolved symbols when zstd_decompress.c is compiled in -mcmode=large mode. The trigger seems to be '__attribute__((__target__("bmi2")))' that throws away '-mcmode=large' commandline flag. Here is the minimal example extracted (gcc-10 generates correct 'movabs/call %reg' code, gcc-11 generates incorrect 'call <symbol>' code): $ bash -x ./mk.bash + args=(-O1 -fno-asynchronous-unwind-tables -fno-ident -mcmodel=large -fno-PIE) + cat a.c // grub builds zstd_decompress.c (zstd.module) in -mcmodel=large // (and -freestanding) mode. grub assumes there will be no dynamic // PLT relocations. grub_memmove() is symbol external (dynamic) // to zstd.module. extern void grub_memmove(void); __attribute__((__target__("bmi2"))) void a_bmi(void) { // expect: // movabsq $grub_memmove, %rbx // call *%rbx // actual (bug): // call grub_memmove for (;;) grub_memmove(); } void a_nobmi(void) { // expect/actual: // movabsq $grub_memmove, %rbx // call *%rbx for (;;) grub_memmove(); } + gcc-10.2.0 -O1 -fno-asynchronous-unwind-tables -fno-ident -mcmodel=large -fno-PIE -S a.c + cat a.s .file "a.c" .text .globl a_bmi .type a_bmi, @function a_bmi: pushq %rbx movabsq $grub_memmove, %rbx .L2: call *%rbx jmp .L2 .size a_bmi, .-a_bmi .globl a_nobmi .type a_nobmi, @function a_nobmi: pushq %rbx movabsq $grub_memmove, %rbx .L5: call *%rbx jmp .L5 .size a_nobmi, .-a_nobmi .section .note.GNU-stack,"",@progbits + gcc-11.0.0 -O1 -fno-asynchronous-unwind-tables -fno-ident -mcmodel=large -fno-PIE -S a.c + cat a.s .file "a.c" .text .globl a_bmi .type a_bmi, @function a_bmi: subq $8, %rsp .L2: call grub_memmove jmp .L2 .size a_bmi, .-a_bmi .globl a_nobmi .type a_nobmi, @function a_nobmi: pushq %rbx movabsq $grub_memmove, %rbx .L5: call *%rbx jmp .L5 .size a_nobmi, .-a_nobmi .section .note.GNU-stack,"",@progbits