public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
@ 2018-02-08 18:05 H.J. Lu
  2018-02-22 14:29 ` Jan Hubicka
  0 siblings, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2018-02-08 18:05 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jan Hubicka

On Sun, Jan 28, 2018 at 11:56 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Jan 27, 2018 at 2:12 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> For
>>
>> ---
>> struct C {
>>   virtual ~C();
>>   virtual void f();
>> };
>>
>> void
>> f (C *p)
>> {
>>   p->f();
>>   p->f();
>> }
>> ---
>>
>> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>>
>> _Z1fP1C:
>> .LFB0:
>>         .cfi_startproc
>>         pushq   %rbx
>>         .cfi_def_cfa_offset 16
>>         .cfi_offset 3, -16
>>         movq    (%rdi), %rax
>>         movq    %rdi, %rbx
>>         jmp     .LIND1
>> .LIND0:
>>         pushq   16(%rax)
>>         jmp     __x86_indirect_thunk
>> .LIND1:
>>         call    .LIND0
>>         movq    (%rbx), %rax
>>         movq    %rbx, %rdi
>>         popq    %rbx
>>         .cfi_def_cfa_offset 8
>>         movq    16(%rax), %rax
>>         jmp     __x86_indirect_thunk_rax
>>         .cfi_endproc
>>
>> x86-64 is supposed to have asynchronous unwind tables by default, but
>> there is nothing that reflects the change in the (relative) frame
>> address after .LIND0.  That region really has to be moved outside of
>> the .cfi_startproc/.cfi_endproc bracket.
>>
>> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
>> branch via register when -mindirect-branch=thunk-extern is used.  Now,
>> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>>
>> _Z1fP1C:
>> .LFB0:
>>         .cfi_startproc
>>         pushq   %rbx
>>         .cfi_def_cfa_offset 16
>>         .cfi_offset 3, -16
>>         movq    (%rdi), %rax
>>         movq    %rdi, %rbx
>>         movq    16(%rax), %rax
>>         call    __x86_indirect_thunk_rax
>>         movq    (%rbx), %rax
>>         movq    %rbx, %rdi
>>         popq    %rbx
>>         .cfi_def_cfa_offset 8
>>         movq    16(%rax), %rax
>>         jmp     __x86_indirect_thunk_rax
>>         .cfi_endproc
>>
>> Now "-mindirect-branch=thunk-extern" is equivalent to
>> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
>> used by Linux kernel.
>>
>> Tested on i686 and x86-64.  OK for trunk?
>>
>> Thanks.
>>
>> H.J.
>> ----
>> gcc/
>>
>>         PR target/84039
>>         * config/i386/constraints.md (Bs): Replace
>>         ix86_indirect_branch_register with
>>         TARGET_INDIRECT_BRANCH_REGISTER.
>>         (Bw): Likewise.
>>         * config/i386/i386.md (indirect_jump): Likewise.
>>         (tablejump): Likewise.
>>         (*sibcall_memory): Likewise.
>>         (*sibcall_value_memory): Likewise.
>>         Peepholes of indirect call and jump via memory: Likewise.
>>         * config/i386/i386.opt: Likewise.
>>         * config/i386/predicates.md (indirect_branch_operand): Likewise.
>>         (GOT_memory_operand): Likewise.
>>         (call_insn_operand): Likewise.
>>         (sibcall_insn_operand): Likewise.
>>         (GOT32_symbol_operand): Likewise.
>>         * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.
>>
>
> Here is the updated patch  to disallow *sibcall_GOT_32 and *sibcall_value_GOT_32
> for TARGET_INDIRECT_BRANCH_REGISTER.
>
> Tested on i686 and x86-64.  OK for trunk?
>

Hi Jan,

https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html

Is OK for trunk?

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-08 18:05 PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER H.J. Lu
@ 2018-02-22 14:29 ` Jan Hubicka
  2018-02-22 14:34   ` H.J. Lu
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Hubicka @ 2018-02-22 14:29 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

> On Sun, Jan 28, 2018 at 11:56 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> > On Sat, Jan 27, 2018 at 2:12 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> >> For
> >>
> >> ---
> >> struct C {
> >>   virtual ~C();
> >>   virtual void f();
> >> };
> >>
> >> void
> >> f (C *p)
> >> {
> >>   p->f();
> >>   p->f();
> >> }
> >> ---
> >>
> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> >>
> >> _Z1fP1C:
> >> .LFB0:
> >>         .cfi_startproc
> >>         pushq   %rbx
> >>         .cfi_def_cfa_offset 16
> >>         .cfi_offset 3, -16
> >>         movq    (%rdi), %rax
> >>         movq    %rdi, %rbx
> >>         jmp     .LIND1
> >> .LIND0:
> >>         pushq   16(%rax)
> >>         jmp     __x86_indirect_thunk
> >> .LIND1:
> >>         call    .LIND0
> >>         movq    (%rbx), %rax
> >>         movq    %rbx, %rdi
> >>         popq    %rbx
> >>         .cfi_def_cfa_offset 8
> >>         movq    16(%rax), %rax
> >>         jmp     __x86_indirect_thunk_rax
> >>         .cfi_endproc
> >>
> >> x86-64 is supposed to have asynchronous unwind tables by default, but
> >> there is nothing that reflects the change in the (relative) frame
> >> address after .LIND0.  That region really has to be moved outside of
> >> the .cfi_startproc/.cfi_endproc bracket.
> >>
> >> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
> >> branch via register when -mindirect-branch=thunk-extern is used.  Now,
> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> >>
> >> _Z1fP1C:
> >> .LFB0:
> >>         .cfi_startproc
> >>         pushq   %rbx
> >>         .cfi_def_cfa_offset 16
> >>         .cfi_offset 3, -16
> >>         movq    (%rdi), %rax
> >>         movq    %rdi, %rbx
> >>         movq    16(%rax), %rax
> >>         call    __x86_indirect_thunk_rax
> >>         movq    (%rbx), %rax
> >>         movq    %rbx, %rdi
> >>         popq    %rbx
> >>         .cfi_def_cfa_offset 8
> >>         movq    16(%rax), %rax
> >>         jmp     __x86_indirect_thunk_rax
> >>         .cfi_endproc
> >>
> >> Now "-mindirect-branch=thunk-extern" is equivalent to
> >> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
> >> used by Linux kernel.
> >>
> >> Tested on i686 and x86-64.  OK for trunk?
> >>
> >> Thanks.
> >>
> >> H.J.
> >> ----
> >> gcc/
> >>
> >>         PR target/84039
> >>         * config/i386/constraints.md (Bs): Replace
> >>         ix86_indirect_branch_register with
> >>         TARGET_INDIRECT_BRANCH_REGISTER.
> >>         (Bw): Likewise.
> >>         * config/i386/i386.md (indirect_jump): Likewise.
> >>         (tablejump): Likewise.
> >>         (*sibcall_memory): Likewise.
> >>         (*sibcall_value_memory): Likewise.
> >>         Peepholes of indirect call and jump via memory: Likewise.
> >>         * config/i386/i386.opt: Likewise.
> >>         * config/i386/predicates.md (indirect_branch_operand): Likewise.
> >>         (GOT_memory_operand): Likewise.
> >>         (call_insn_operand): Likewise.
> >>         (sibcall_insn_operand): Likewise.
> >>         (GOT32_symbol_operand): Likewise.
> >>         * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.
> >>
> >
> > Here is the updated patch  to disallow *sibcall_GOT_32 and *sibcall_value_GOT_32
> > for TARGET_INDIRECT_BRANCH_REGISTER.
> >
> > Tested on i686 and x86-64.  OK for trunk?
> >
> 
> Hi Jan,
> 
> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
> 
> Is OK for trunk?

I see that using register makes the problem go away and pushing address to stack
seemed bit odd anyway. However how does this work on other types of thunk?

Honza

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 14:29 ` Jan Hubicka
@ 2018-02-22 14:34   ` H.J. Lu
  2018-02-22 14:38     ` Jan Hubicka
  0 siblings, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2018-02-22 14:34 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches

On Thu, Feb 22, 2018 at 6:29 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> On Sun, Jan 28, 2018 at 11:56 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> > On Sat, Jan 27, 2018 at 2:12 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> >> For
>> >>
>> >> ---
>> >> struct C {
>> >>   virtual ~C();
>> >>   virtual void f();
>> >> };
>> >>
>> >> void
>> >> f (C *p)
>> >> {
>> >>   p->f();
>> >>   p->f();
>> >> }
>> >> ---
>> >>
>> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>> >>
>> >> _Z1fP1C:
>> >> .LFB0:
>> >>         .cfi_startproc
>> >>         pushq   %rbx
>> >>         .cfi_def_cfa_offset 16
>> >>         .cfi_offset 3, -16
>> >>         movq    (%rdi), %rax
>> >>         movq    %rdi, %rbx
>> >>         jmp     .LIND1
>> >> .LIND0:
>> >>         pushq   16(%rax)
>> >>         jmp     __x86_indirect_thunk
>> >> .LIND1:
>> >>         call    .LIND0
>> >>         movq    (%rbx), %rax
>> >>         movq    %rbx, %rdi
>> >>         popq    %rbx
>> >>         .cfi_def_cfa_offset 8
>> >>         movq    16(%rax), %rax
>> >>         jmp     __x86_indirect_thunk_rax
>> >>         .cfi_endproc
>> >>
>> >> x86-64 is supposed to have asynchronous unwind tables by default, but
>> >> there is nothing that reflects the change in the (relative) frame
>> >> address after .LIND0.  That region really has to be moved outside of
>> >> the .cfi_startproc/.cfi_endproc bracket.
>> >>
>> >> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
>> >> branch via register when -mindirect-branch=thunk-extern is used.  Now,
>> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>> >>
>> >> _Z1fP1C:
>> >> .LFB0:
>> >>         .cfi_startproc
>> >>         pushq   %rbx
>> >>         .cfi_def_cfa_offset 16
>> >>         .cfi_offset 3, -16
>> >>         movq    (%rdi), %rax
>> >>         movq    %rdi, %rbx
>> >>         movq    16(%rax), %rax
>> >>         call    __x86_indirect_thunk_rax
>> >>         movq    (%rbx), %rax
>> >>         movq    %rbx, %rdi
>> >>         popq    %rbx
>> >>         .cfi_def_cfa_offset 8
>> >>         movq    16(%rax), %rax
>> >>         jmp     __x86_indirect_thunk_rax
>> >>         .cfi_endproc
>> >>
>> >> Now "-mindirect-branch=thunk-extern" is equivalent to
>> >> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
>> >> used by Linux kernel.
>> >>
>> >> Tested on i686 and x86-64.  OK for trunk?
>> >>
>> >> Thanks.
>> >>
>> >> H.J.
>> >> ----
>> >> gcc/
>> >>
>> >>         PR target/84039
>> >>         * config/i386/constraints.md (Bs): Replace
>> >>         ix86_indirect_branch_register with
>> >>         TARGET_INDIRECT_BRANCH_REGISTER.
>> >>         (Bw): Likewise.
>> >>         * config/i386/i386.md (indirect_jump): Likewise.
>> >>         (tablejump): Likewise.
>> >>         (*sibcall_memory): Likewise.
>> >>         (*sibcall_value_memory): Likewise.
>> >>         Peepholes of indirect call and jump via memory: Likewise.
>> >>         * config/i386/i386.opt: Likewise.
>> >>         * config/i386/predicates.md (indirect_branch_operand): Likewise.
>> >>         (GOT_memory_operand): Likewise.
>> >>         (call_insn_operand): Likewise.
>> >>         (sibcall_insn_operand): Likewise.
>> >>         (GOT32_symbol_operand): Likewise.
>> >>         * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.
>> >>
>> >
>> > Here is the updated patch  to disallow *sibcall_GOT_32 and *sibcall_value_GOT_32
>> > for TARGET_INDIRECT_BRANCH_REGISTER.
>> >
>> > Tested on i686 and x86-64.  OK for trunk?
>> >
>>
>> Hi Jan,
>>
>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
>>
>> Is OK for trunk?
>
> I see that using register makes the problem go away and pushing address to stack
> seemed bit odd anyway. However how does this work on other types of thunk?

Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
to use -mindirect-branch=thunk-extern in user space to support CET in a single
binary.  So at the end of the day, only
-mindirect-branch=thunk-extern will be used.


-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 14:34   ` H.J. Lu
@ 2018-02-22 14:38     ` Jan Hubicka
  2018-02-22 16:34       ` H.J. Lu
                         ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Jan Hubicka @ 2018-02-22 14:38 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

> >>
> >> Hi Jan,
> >>
> >> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
> >>
> >> Is OK for trunk?
> >
> > I see that using register makes the problem go away and pushing address to stack
> > seemed bit odd anyway. However how does this work on other types of thunk?
> 
> Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
> to use -mindirect-branch=thunk-extern in user space to support CET in a single
> binary.  So at the end of the day, only
> -mindirect-branch=thunk-extern will be used.

OK, so it is about the fact that we do not really want to support all
-mindirect-branch options in the future? If we don't want to support the correctly,
I wonder why we are including them at all.  Shall we at least output warning/sorry
when user tries other thunk type with stack unwinding enabled?
(does Kernel use it?)

Honza
> 
> 
> -- 
> H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 14:38     ` Jan Hubicka
@ 2018-02-22 16:34       ` H.J. Lu
  2018-02-22 17:10       ` Jeff Law
  2018-02-26 15:47       ` Jan Hubicka
  2 siblings, 0 replies; 15+ messages in thread
From: H.J. Lu @ 2018-02-22 16:34 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches

On Thu, Feb 22, 2018 at 6:38 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> >>
>> >> Hi Jan,
>> >>
>> >> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
>> >>
>> >> Is OK for trunk?
>> >
>> > I see that using register makes the problem go away and pushing address to stack
>> > seemed bit odd anyway. However how does this work on other types of thunk?
>>
>> Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
>> to use -mindirect-branch=thunk-extern in user space to support CET in a single
>> binary.  So at the end of the day, only
>> -mindirect-branch=thunk-extern will be used.
>
> OK, so it is about the fact that we do not really want to support all
> -mindirect-branch options in the future? If we don't want to support the correctly,
> I wonder why we are including them at all.  Shall we at least output warning/sorry

-mindirect-branch= implementation changed over time while
experimenting different
approaches.  I didn't remove the old ones when I added new ones.  We
should remove
others and only keep -mindirect-branch=thunk-extern with my proposal
to support CET
with -mindirect-branch=thunk-extern.

> when user tries other thunk type with stack unwinding enabled?

This is on my TODO list.

> (does Kernel use it?)

No, kernel doesn't use it.


-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 14:38     ` Jan Hubicka
  2018-02-22 16:34       ` H.J. Lu
@ 2018-02-22 17:10       ` Jeff Law
  2018-02-22 17:33         ` H.J. Lu
  2018-02-28  9:39         ` Steve Beattie
  2018-02-26 15:47       ` Jan Hubicka
  2 siblings, 2 replies; 15+ messages in thread
From: Jeff Law @ 2018-02-22 17:10 UTC (permalink / raw)
  To: Jan Hubicka, H.J. Lu; +Cc: GCC Patches

On 02/22/2018 07:38 AM, Jan Hubicka wrote:
>>>>
>>>> Hi Jan,
>>>>
>>>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
>>>>
>>>> Is OK for trunk?
>>>
>>> I see that using register makes the problem go away and pushing address to stack
>>> seemed bit odd anyway. However how does this work on other types of thunk?
>>
>> Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
>> to use -mindirect-branch=thunk-extern in user space to support CET in a single
>> binary.  So at the end of the day, only
>> -mindirect-branch=thunk-extern will be used.
> 
> OK, so it is about the fact that we do not really want to support all
> -mindirect-branch options in the future? If we don't want to support the correctly,
> I wonder why we are including them at all.  Shall we at least output warning/sorry
> when user tries other thunk type with stack unwinding enabled?
> (does Kernel use it?)
A few notes.

1. It's not even clear at this time that retpolining user space binaries
makes any sense at all.   SO before doing anything to make this easier
I'd like to see a justification for why it's really needed.

2. On the other hand, the existing thunk options do make it easier to
test independent of hte kernel.  ie, I can turn on inline thunks by
default and test things in user space (ie, do thunks generally work
properly).

Jeff

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 17:10       ` Jeff Law
@ 2018-02-22 17:33         ` H.J. Lu
  2018-02-23 20:53           ` H.J. Lu
  2018-02-28  9:39         ` Steve Beattie
  1 sibling, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2018-02-22 17:33 UTC (permalink / raw)
  To: Jeff Law; +Cc: Jan Hubicka, GCC Patches

On Thu, Feb 22, 2018 at 9:10 AM, Jeff Law <law@redhat.com> wrote:
> On 02/22/2018 07:38 AM, Jan Hubicka wrote:
>>>>>
>>>>> Hi Jan,
>>>>>
>>>>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
>>>>>
>>>>> Is OK for trunk?
>>>>
>>>> I see that using register makes the problem go away and pushing address to stack
>>>> seemed bit odd anyway. However how does this work on other types of thunk?
>>>
>>> Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
>>> to use -mindirect-branch=thunk-extern in user space to support CET in a single
>>> binary.  So at the end of the day, only
>>> -mindirect-branch=thunk-extern will be used.
>>
>> OK, so it is about the fact that we do not really want to support all
>> -mindirect-branch options in the future? If we don't want to support the correctly,
>> I wonder why we are including them at all.  Shall we at least output warning/sorry
>> when user tries other thunk type with stack unwinding enabled?
>> (does Kernel use it?)
> A few notes.
>
> 1. It's not even clear at this time that retpolining user space binaries
> makes any sense at all.   SO before doing anything to make this easier
> I'd like to see a justification for why it's really needed.

Hi Jeff,

Which part were commenting? My patch to add TARGET_INDIRECT_BRANCH_REGISTER
or removing -mindirect-branch choices?

> 2. On the other hand, the existing thunk options do make it easier to
> test independent of hte kernel.  ie, I can turn on inline thunks by
> default and test things in user space (ie, do thunks generally work
> properly).

It sounds reasonable.


-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 17:33         ` H.J. Lu
@ 2018-02-23 20:53           ` H.J. Lu
  0 siblings, 0 replies; 15+ messages in thread
From: H.J. Lu @ 2018-02-23 20:53 UTC (permalink / raw)
  To: Jeff Law; +Cc: Jan Hubicka, GCC Patches

On Thu, Feb 22, 2018 at 9:32 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 22, 2018 at 9:10 AM, Jeff Law <law@redhat.com> wrote:
>> On 02/22/2018 07:38 AM, Jan Hubicka wrote:
>>>>>>
>>>>>> Hi Jan,
>>>>>>
>>>>>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg02233.html
>>>>>>
>>>>>> Is OK for trunk?
>>>>>
>>>>> I see that using register makes the problem go away and pushing address to stack
>>>>> seemed bit odd anyway. However how does this work on other types of thunk?
>>>>
>>>> Kernel only uses  -mindirect-branch=thunk-extern.  I am working on a proposal
>>>> to use -mindirect-branch=thunk-extern in user space to support CET in a single
>>>> binary.  So at the end of the day, only
>>>> -mindirect-branch=thunk-extern will be used.
>>>
>>> OK, so it is about the fact that we do not really want to support all
>>> -mindirect-branch options in the future? If we don't want to support the correctly,
>>> I wonder why we are including them at all.  Shall we at least output warning/sorry
>>> when user tries other thunk type with stack unwinding enabled?
>>> (does Kernel use it?)
>> A few notes.
>>
>> 1. It's not even clear at this time that retpolining user space binaries
>> makes any sense at all.   SO before doing anything to make this easier
>> I'd like to see a justification for why it's really needed.
>
> Hi Jeff,
>
> Which part were commenting? My patch to add TARGET_INDIRECT_BRANCH_REGISTER
> or removing -mindirect-branch choices?

Is my patch OK for trunk?

>> 2. On the other hand, the existing thunk options do make it easier to
>> test independent of hte kernel.  ie, I can turn on inline thunks by
>> default and test things in user space (ie, do thunks generally work
>> properly).
>
> It sounds reasonable.
>

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 14:38     ` Jan Hubicka
  2018-02-22 16:34       ` H.J. Lu
  2018-02-22 17:10       ` Jeff Law
@ 2018-02-26 15:47       ` Jan Hubicka
  2018-02-26 16:22         ` H.J. Lu
  2 siblings, 1 reply; 15+ messages in thread
From: Jan Hubicka @ 2018-02-26 15:47 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

Hi,
my main concern about the patch is that we now have -mindirect-branch=thunk-extern
which is intended to work well and is used by kernel, but we also have other modes
that are documented and as such they should work but they may lead to invalid
unwind info (or did I miss anything imporant here?).
Why we can't fix the others as well? 

Honza

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-26 15:47       ` Jan Hubicka
@ 2018-02-26 16:22         ` H.J. Lu
  2018-02-26 16:54           ` Jan Hubicka
  0 siblings, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2018-02-26 16:22 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1986 bytes --]

On Mon, Feb 26, 2018 at 7:47 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> my main concern about the patch is that we now have -mindirect-branch=thunk-extern
> which is intended to work well and is used by kernel, but we also have other modes
> that are documented and as such they should work but they may lead to invalid
> unwind info (or did I miss anything imporant here?).
> Why we can't fix the others as well?
>

I took a closer look at my commit message.  It does leave an impression that
only  -mindirect-branch=thunk-extern is fixed.  But in fact, all
-mindirect-branch=
choices are fixed.

1.  -mindirect-branch=thunk generates:

       .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movq    (%rdi), %rax
        movq    %rdi, %rbx
        movq    16(%rax), %rax
        call    __x86_indirect_thunk_rax
        movq    (%rbx), %rax
        movq    %rbx, %rdi
        popq    %rbx
        .cfi_def_cfa_offset 8
        movq    16(%rax), %rax
        jmp     __x86_indirect_thunk_rax
        .cfi_endproc

2.  -mindirect-branch=thunk-inline generates:

       .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movq    (%rdi), %rax
        movq    %rdi, %rbx
        movq    16(%rax), %rax
        jmp     .LIND1
.LIND0:
        call    .LIND3
.LIND2:
        pause
        lfence
        jmp     .LIND2
.LIND3:
        mov     %rax, (%rsp)
        ret
.LIND1:
        call    .LIND0
        movq    (%rbx), %rax
        movq    %rbx, %rdi
        popq    %rbx
        .cfi_def_cfa_offset 8
        movq    16(%rax), %rax
        call    .LIND5
.LIND4:
        pause
        lfence
        jmp     .LIND4
.LIND5:
        mov     %rax, (%rsp)
        ret
        .cfi_endproc

I updated the commit message with

This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
branch via register whenever -mindirect-branch= is used.

OK for trunk?

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-i386-Add-TARGET_INDIRECT_BRANCH_REGISTER.patch --]
[-- Type: text/x-patch, Size: 53617 bytes --]

From bd0672bd070da6fa4ff630540c1d87df3e8fdd53 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 26 Jan 2018 15:54:25 -0800
Subject: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER

For

---
struct C {
  virtual ~C();
  virtual void f();
};

void
f (C *p)
{
  p->f();
  p->f();
}
---

-mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:

_Z1fP1C:
.LFB0:
        .cfi_startproc
        pushq   %rbx
        .cfi_def_cfa_offset 16
        .cfi_offset 3, -16
        movq    (%rdi), %rax
        movq    %rdi, %rbx
        jmp     .LIND1
.LIND0:
        pushq   16(%rax)
        jmp     __x86_indirect_thunk
.LIND1:
        call    .LIND0
        movq    (%rbx), %rax
        movq    %rbx, %rdi
        popq    %rbx
        .cfi_def_cfa_offset 8
        movq    16(%rax), %rax
        jmp     __x86_indirect_thunk_rax
        .cfi_endproc

x86-64 is supposed to have asynchronous unwind tables by default, but
there is nothing that reflects the change in the (relative) frame
address after .LIND0.  That region really has to be moved outside of
the .cfi_startproc/.cfi_endproc bracket.

This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
branch via register whenever -mindirect-branch= is used.  Now,
-mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:

_Z1fP1C:
.LFB0:
	.cfi_startproc
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	movq	(%rdi), %rax
	movq	%rdi, %rbx
	movq	16(%rax), %rax
	call	__x86_indirect_thunk_rax
	movq	(%rbx), %rax
	movq	%rbx, %rdi
	popq	%rbx
	.cfi_def_cfa_offset 8
	movq	16(%rax), %rax
	jmp	__x86_indirect_thunk_rax
	.cfi_endproc

so that "-mindirect-branch=thunk-extern" is equivalent to
"-mindirect-branch=thunk-extern -mindirect-branch-register", which is
used by Linux kernel.

gcc/

	PR target/84039
	* config/i386/constraints.md (Bs): Replace
	ix86_indirect_branch_register with
	TARGET_INDIRECT_BRANCH_REGISTER.
	(Bw): Likewise.
	* config/i386/i386.md (indirect_jump): Likewise.
	(tablejump): Likewise.
	(*sibcall_memory): Likewise.
	(*sibcall_value_memory): Likewise.
	Peepholes of indirect call and jump via memory: Likewise.
	(*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER.
	(*sibcall_value_GOT_32): Likewise.
	* config/i386/i386.opt: Likewise.
	* config/i386/predicates.md (indirect_branch_operand): Likewise.
	(GOT_memory_operand): Likewise.
	(call_insn_operand): Likewise.
	(sibcall_insn_operand): Likewise.
	(GOT32_symbol_operand): Likewise.
	* config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.

gcc/testsuite/

	PR target/84039
	* gcc.target/i386/indirect-thunk-1.c: Updated.
	* gcc.target/i386/indirect-thunk-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-3.c: Likewise.
	* gcc.target/i386/indirect-thunk-4.c: Likewise.
	* gcc.target/i386/indirect-thunk-5.c: Likewise.
	* gcc.target/i386/indirect-thunk-6.c: Likewise.
	* gcc.target/i386/indirect-thunk-7.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
	* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
	* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
	* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
	* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
	* gcc.target/i386/ret-thunk-9.c: Likewise.
	* gcc.target/i386/ret-thunk-10.c: Likewise.
	* gcc.target/i386/ret-thunk-11.c: Likewise.
	* gcc.target/i386/ret-thunk-12.c: Likewise.
	* gcc.target/i386/ret-thunk-13.c: Likewise.
	* gcc.target/i386/ret-thunk-14.c: Likewise.
	* gcc.target/i386/ret-thunk-15.c: Likewise.
---
 gcc/config/i386/constraints.md                     |  4 ++--
 gcc/config/i386/i386.h                             |  4 ++++
 gcc/config/i386/i386.md                            | 28 +++++++++++++---------
 gcc/config/i386/predicates.md                      |  6 ++---
 gcc/testsuite/gcc.target/i386/indirect-thunk-1.c   |  5 ++--
 gcc/testsuite/gcc.target/i386/indirect-thunk-2.c   |  5 ++--
 gcc/testsuite/gcc.target/i386/indirect-thunk-3.c   |  5 ++--
 gcc/testsuite/gcc.target/i386/indirect-thunk-4.c   |  5 ++--
 gcc/testsuite/gcc.target/i386/indirect-thunk-5.c   |  6 +++--
 gcc/testsuite/gcc.target/i386/indirect-thunk-6.c   | 12 ++++++----
 gcc/testsuite/gcc.target/i386/indirect-thunk-7.c   |  5 ++--
 .../gcc.target/i386/indirect-thunk-attr-1.c        |  5 ++--
 .../gcc.target/i386/indirect-thunk-attr-2.c        |  5 ++--
 .../gcc.target/i386/indirect-thunk-attr-3.c        |  3 +--
 .../gcc.target/i386/indirect-thunk-attr-4.c        |  3 +--
 .../gcc.target/i386/indirect-thunk-attr-5.c        |  9 ++++---
 .../gcc.target/i386/indirect-thunk-attr-6.c        |  9 ++++---
 .../gcc.target/i386/indirect-thunk-attr-7.c        |  5 ++--
 .../gcc.target/i386/indirect-thunk-bnd-1.c         |  6 ++---
 .../gcc.target/i386/indirect-thunk-bnd-2.c         |  6 ++---
 .../gcc.target/i386/indirect-thunk-bnd-3.c         |  5 ++--
 .../gcc.target/i386/indirect-thunk-bnd-4.c         |  7 +++---
 .../gcc.target/i386/indirect-thunk-extern-1.c      |  5 ++--
 .../gcc.target/i386/indirect-thunk-extern-2.c      |  5 ++--
 .../gcc.target/i386/indirect-thunk-extern-3.c      |  9 ++++---
 .../gcc.target/i386/indirect-thunk-extern-4.c      |  6 ++---
 .../gcc.target/i386/indirect-thunk-extern-5.c      |  6 +++--
 .../gcc.target/i386/indirect-thunk-extern-6.c      |  8 +++----
 .../gcc.target/i386/indirect-thunk-extern-7.c      |  5 ++--
 .../gcc.target/i386/indirect-thunk-inline-1.c      |  2 +-
 .../gcc.target/i386/indirect-thunk-inline-2.c      |  2 +-
 .../gcc.target/i386/indirect-thunk-inline-3.c      |  2 +-
 .../gcc.target/i386/indirect-thunk-inline-4.c      |  2 +-
 .../gcc.target/i386/indirect-thunk-inline-5.c      |  3 ++-
 .../gcc.target/i386/indirect-thunk-inline-6.c      |  3 ++-
 .../gcc.target/i386/indirect-thunk-inline-7.c      |  4 ++--
 gcc/testsuite/gcc.target/i386/ret-thunk-10.c       |  9 +++----
 gcc/testsuite/gcc.target/i386/ret-thunk-11.c       |  9 +++----
 gcc/testsuite/gcc.target/i386/ret-thunk-12.c       |  8 +++----
 gcc/testsuite/gcc.target/i386/ret-thunk-13.c       |  5 ++--
 gcc/testsuite/gcc.target/i386/ret-thunk-14.c       |  7 +++---
 gcc/testsuite/gcc.target/i386/ret-thunk-15.c       |  7 +++---
 gcc/testsuite/gcc.target/i386/ret-thunk-9.c        | 13 ++++------
 43 files changed, 127 insertions(+), 141 deletions(-)

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 664e906b311..d026968c4c9 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -225,7 +225,7 @@
 
 (define_constraint "Bs"
   "@internal Sibcall memory operand."
-  (ior (and (not (match_test "ix86_indirect_branch_register"))
+  (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
 	    (not (match_test "TARGET_X32"))
 	    (match_operand 0 "sibcall_memory_operand"))
        (and (match_test "TARGET_X32 && Pmode == DImode")
@@ -233,7 +233,7 @@
 
 (define_constraint "Bw"
   "@internal Call memory operand."
-  (ior (and (not (match_test "ix86_indirect_branch_register"))
+  (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
 	    (not (match_test "TARGET_X32"))
 	    (match_operand 0 "memory_operand"))
        (and (match_test "TARGET_X32 && Pmode == DImode")
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9d864501d4f..6f3ae683d74 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2709,6 +2709,10 @@ extern void debug_dispatch_window (int);
 #define TARGET_PREFER_AVX256	(TARGET_PREFER_AVX128 \
 				 || prefer_vector_width_type == PVW_AVX256)
 
+#define TARGET_INDIRECT_BRANCH_REGISTER \
+  (ix86_indirect_branch_register \
+   || cfun->machine->indirect_branch_type != indirect_branch_keep)
+
 #define IX86_HLE_ACQUIRE (1 << 16)
 #define IX86_HLE_RELEASE (1 << 17)
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f271278ed58..85e4b07cd0f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12311,7 +12311,7 @@
   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
   ""
 {
-  if (TARGET_X32 || ix86_indirect_branch_register)
+  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
     operands[0] = convert_memory_address (word_mode, operands[0]);
   cfun->machine->has_local_indirect_jump = true;
 })
@@ -12365,7 +12365,7 @@
 					 OPTAB_DIRECT);
     }
 
-  if (TARGET_X32 || ix86_indirect_branch_register)
+  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
     operands[0] = convert_memory_address (word_mode, operands[0]);
   cfun->machine->has_local_indirect_jump = true;
 })
@@ -12595,7 +12595,10 @@
 		     (match_operand:SI 0 "register_no_elim_operand" "U")
 		     (match_operand:SI 1 "GOT32_symbol_operand"))))
 	 (match_operand 2))]
-  "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+  "!TARGET_MACHO
+  && !TARGET_64BIT
+  && !TARGET_INDIRECT_BRANCH_REGISTER
+  && SIBLING_CALL_P (insn)"
 {
   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
   fnaddr = gen_const_mem (SImode, fnaddr);
@@ -12614,7 +12617,7 @@
   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
 	 (match_operand 1))
    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
-  "!TARGET_X32 && !ix86_indirect_branch_register"
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
   "* return ix86_output_call_insn (insn, operands[0]);"
   [(set_attr "type" "call")])
 
@@ -12624,7 +12627,7 @@
    (call (mem:QI (match_dup 0))
 	 (match_operand 3))]
   "!TARGET_X32
-   && !ix86_indirect_branch_register
+   && !TARGET_INDIRECT_BRANCH_REGISTER
    && SIBLING_CALL_P (peep2_next_insn (1))
    && !reg_mentioned_p (operands[0],
 			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
@@ -12639,7 +12642,7 @@
    (call (mem:QI (match_dup 0))
 	 (match_operand 3))]
   "!TARGET_X32
-   && !ix86_indirect_branch_register
+   && !TARGET_INDIRECT_BRANCH_REGISTER
    && SIBLING_CALL_P (peep2_next_insn (2))
    && !reg_mentioned_p (operands[0],
 			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
@@ -12737,7 +12740,7 @@
         (match_operand:W 1 "memory_operand"))
    (set (pc) (match_dup 0))]
   "!TARGET_X32
-   && !ix86_indirect_branch_register
+   && !TARGET_INDIRECT_BRANCH_REGISTER
    && peep2_reg_dead_p (2, operands[0])"
   [(set (pc) (match_dup 1))])
 
@@ -12798,7 +12801,10 @@
 			  (match_operand:SI 1 "register_no_elim_operand" "U")
 			  (match_operand:SI 2 "GOT32_symbol_operand"))))
 	 (match_operand 3)))]
-  "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
+  "!TARGET_MACHO
+   && !TARGET_64BIT
+   && !TARGET_INDIRECT_BRANCH_REGISTER
+   && SIBLING_CALL_P (insn)"
 {
   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
   fnaddr = gen_const_mem (SImode, fnaddr);
@@ -12819,7 +12825,7 @@
  	(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
 	      (match_operand 2)))
    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
-  "!TARGET_X32 && !ix86_indirect_branch_register"
+  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
   "* return ix86_output_call_insn (insn, operands[1]);"
   [(set_attr "type" "callv")])
 
@@ -12830,7 +12836,7 @@
    (call (mem:QI (match_dup 0))
 		 (match_operand 3)))]
   "!TARGET_X32
-   && !ix86_indirect_branch_register
+   && !TARGET_INDIRECT_BRANCH_REGISTER
    && SIBLING_CALL_P (peep2_next_insn (1))
    && !reg_mentioned_p (operands[0],
 			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
@@ -12847,7 +12853,7 @@
 	(call (mem:QI (match_dup 0))
 	      (match_operand 3)))]
   "!TARGET_X32
-   && !ix86_indirect_branch_register
+   && !TARGET_INDIRECT_BRANCH_REGISTER
    && SIBLING_CALL_P (peep2_next_insn (2))
    && !reg_mentioned_p (operands[0],
 			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 2f2393b9e3e..f6cdc86fc5f 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -665,7 +665,7 @@
 ;; Test for a valid operand for indirect branch.
 (define_predicate "indirect_branch_operand"
   (ior (match_operand 0 "register_operand")
-       (and (not (match_test "ix86_indirect_branch_register"))
+       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
 	    (not (match_test "TARGET_X32"))
 	    (match_operand 0 "memory_operand"))))
 
@@ -709,7 +709,7 @@
   (ior (match_test "constant_call_address_operand
 		     (op, mode == VOIDmode ? mode : Pmode)")
        (match_operand 0 "call_register_no_elim_operand")
-       (and (not (match_test "ix86_indirect_branch_register"))
+       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
 	    (ior (and (not (match_test "TARGET_X32"))
 		      (match_operand 0 "memory_operand"))
 		 (and (match_test "TARGET_X32 && Pmode == DImode")
@@ -720,7 +720,7 @@
   (ior (match_test "constant_call_address_operand
 		     (op, mode == VOIDmode ? mode : Pmode)")
        (match_operand 0 "register_no_elim_operand")
-       (and (not (match_test "ix86_indirect_branch_register"))
+       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
 	    (ior (and (not (match_test "TARGET_X32"))
 		      (match_operand 0 "sibcall_memory_operand"))
 		 (and (match_test "TARGET_X32 && Pmode == DImode")
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
index 60d09881a99..6e94d2c4865 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
@@ -11,9 +11,8 @@ male_indirect_jump (long offset)
   dispatch(offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
index aac75163794..3c467078964 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
@@ -11,9 +11,8 @@ male_indirect_jump (long offset)
   dispatch[offset](offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
index dab7ac2ef25..e4c9b885d50 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
@@ -12,9 +12,8 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
index 44cc5f52f45..b22554ae282 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
@@ -12,9 +12,8 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
index fcaa18d10b7..fb26c005e80 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
@@ -9,8 +9,10 @@ foo (void)
   bar ();
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
index 1490f5336ca..8bc45ff68ce 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
@@ -10,9 +10,13 @@ foo (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 { target x32 } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
+/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
 /* { dg-final { scan-assembler {\tpause} } } */
 /* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
index 17c2d0faf88..3c72036dbaf 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
@@ -35,9 +35,8 @@ bar (int i)
     }
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
index 9194ccf3cbc..7106407b83d 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
@@ -14,9 +14,8 @@ male_indirect_jump (long offset)
   dispatch(offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
index e51f261a612..27c7e5b029b 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
@@ -12,9 +12,8 @@ male_indirect_jump (long offset)
   dispatch[offset](offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
index 4aeec1833cd..89a2bac8403 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
@@ -14,10 +14,9 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler {\tpause} } } */
 /* { dg-final { scan-assembler {\tlfence} } } */
 /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
index ac0e5999f63..3eb83c3779a 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
@@ -13,10 +13,9 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler {\tpause} } } */
 /* { dg-final { scan-assembler {\tlfence} } } */
 /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
index 573cf1ef09e..0098dd1133d 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
@@ -14,9 +14,8 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
index b2b37fc6e2e..ece8de15a4b 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
@@ -13,9 +13,8 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
index 4a43e199931..d53fc887dcc 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -36,9 +36,8 @@ bar (int i)
     }
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
index ac84ab623fa..73d16baddc7 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
@@ -10,9 +10,9 @@ foo (void)
   dispatch (buf);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */
+/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "bnd ret" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
index ce655e8be1c..856751ac224 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
@@ -11,10 +11,8 @@ foo (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */
 /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "bnd ret" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
index d34485a0010..42312f65588 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
@@ -10,8 +10,9 @@ foo (void)
   bar (buf);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */
+/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */
+/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "bnd ret" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
index a5fc4a23351..8850f2ffca4 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
@@ -11,10 +11,9 @@ foo (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */
-/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */
+/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */
+/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 1 } } */
 /* { dg-final { scan-assembler "bnd ret" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
 /* { dg-final { scan-assembler {\tlfence} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
index 579441f250e..c09dd0afd2d 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
@@ -11,9 +11,8 @@ male_indirect_jump (long offset)
   dispatch(offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
index c92e6f2b02d..826425a5115 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
@@ -11,9 +11,8 @@ male_indirect_jump (long offset)
   dispatch[offset](offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
index d9964c25bbd..385626850a2 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
@@ -12,9 +12,8 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
+/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
index d4dca4dc5fe..1ae49b137ca 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
@@ -12,9 +12,7 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
 /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
index 5c07e02df6a..53282390977 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
@@ -9,8 +9,10 @@ foo (void)
   bar ();
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
index 3eb440693a0..8ae43482d0c 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
@@ -10,8 +10,8 @@ foo (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
-/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
-/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
index aece9383697..2b9a33e93dc 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -35,9 +35,8 @@ bar (int i)
     }
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
index 3aba5e8c81f..869d9040838 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
@@ -11,7 +11,7 @@ male_indirect_jump (long offset)
   dispatch(offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
index 0f0181d6672..c5c16ed8bd8 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
@@ -11,7 +11,7 @@ male_indirect_jump (long offset)
   dispatch[offset](offset);
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
index 2eef6f35a75..4a63ebed8ab 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
@@ -12,7 +12,7 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times {\tpause} 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
index e825a10f14c..a395ffca018 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
@@ -12,7 +12,7 @@ male_indirect_jump (long offset)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times {\tpause} 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
index c6d77e10352..21cbfd39582 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
@@ -9,7 +9,8 @@ foo (void)
   bar ();
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
index 6454827b780..d1300f18dc7 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
@@ -10,7 +10,8 @@ foo (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
+/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
 /* { dg-final { scan-assembler-times {\tpause} 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
index c67066cf197..ea009245a58 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
@@ -35,8 +35,8 @@ bar (int i)
     }
 }
 
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%(r|e)ax" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler {\tpause} } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
index 6de9b8c9f4f..b245d21b002 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
@@ -15,9 +15,6 @@ foo (void)
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
 /* { dg-final { scan-assembler-times {\tpause} 2 } } */
 /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } }  } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
index 36598037541..ce0543e1181 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
@@ -15,9 +15,6 @@ foo (void)
 /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
index 5fb1a4de776..3b0023a0a6d 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
@@ -15,8 +15,6 @@ foo (void)
 /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
-/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
index fd5b41fdd3f..55f156c4376 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
@@ -14,9 +14,8 @@ foo (void)
 /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
 /* { dg-final { scan-assembler-times {\tpause} 2 } } */
 /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
 /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
 /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */
-/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
index d606373ead1..1c790436a53 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
@@ -16,7 +16,6 @@ foo (void)
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
index 2038644aa59..bc2bedf5a9c 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
@@ -16,7 +16,6 @@ foo (void)
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-times {\tpause} 1 } } */
 /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
index d34dd4e6dc7..b75fc9219b0 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
@@ -14,11 +14,8 @@ foo (void)
 /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
-/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
-/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
-/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */
-/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
-/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
-/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
+/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
+/* { dg-final { scan-assembler-times {\tpause} 2 } } */
+/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
+/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
-- 
2.14.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-26 16:22         ` H.J. Lu
@ 2018-02-26 16:54           ` Jan Hubicka
  2018-02-27 12:49             ` H.J. Lu
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Hubicka @ 2018-02-26 16:54 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

> On Mon, Feb 26, 2018 at 7:47 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> > Hi,
> > my main concern about the patch is that we now have -mindirect-branch=thunk-extern
> > which is intended to work well and is used by kernel, but we also have other modes
> > that are documented and as such they should work but they may lead to invalid
> > unwind info (or did I miss anything imporant here?).
> > Why we can't fix the others as well?
> >
> 
> I took a closer look at my commit message.  It does leave an impression that
> only  -mindirect-branch=thunk-extern is fixed.  But in fact, all
> -mindirect-branch=
> choices are fixed.

I see, sorry for confussion!
> 
> 1.  -mindirect-branch=thunk generates:
> 
>        .cfi_startproc
>         pushq   %rbx
>         .cfi_def_cfa_offset 16
>         .cfi_offset 3, -16
>         movq    (%rdi), %rax
>         movq    %rdi, %rbx
>         movq    16(%rax), %rax
>         call    __x86_indirect_thunk_rax
>         movq    (%rbx), %rax
>         movq    %rbx, %rdi
>         popq    %rbx
>         .cfi_def_cfa_offset 8
>         movq    16(%rax), %rax
>         jmp     __x86_indirect_thunk_rax
>         .cfi_endproc
> 
> 2.  -mindirect-branch=thunk-inline generates:
> 
>        .cfi_startproc
>         pushq   %rbx
>         .cfi_def_cfa_offset 16
>         .cfi_offset 3, -16
>         movq    (%rdi), %rax
>         movq    %rdi, %rbx
>         movq    16(%rax), %rax
>         jmp     .LIND1
> .LIND0:
>         call    .LIND3
> .LIND2:
>         pause
>         lfence
>         jmp     .LIND2
> .LIND3:
>         mov     %rax, (%rsp)
>         ret
> .LIND1:
>         call    .LIND0
>         movq    (%rbx), %rax
>         movq    %rbx, %rdi
>         popq    %rbx
>         .cfi_def_cfa_offset 8
>         movq    16(%rax), %rax
>         call    .LIND5
> .LIND4:
>         pause
>         lfence
>         jmp     .LIND4
> .LIND5:
>         mov     %rax, (%rsp)
>         ret
>         .cfi_endproc
> 
> I updated the commit message with
> 
> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
> branch via register whenever -mindirect-branch= is used.
> 
> OK for trunk?
> 
> Thanks.
> 
> -- 
> H.J.

> From bd0672bd070da6fa4ff630540c1d87df3e8fdd53 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Fri, 26 Jan 2018 15:54:25 -0800
> Subject: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
> 
> For
> 
> ---
> struct C {
>   virtual ~C();
>   virtual void f();
> };
> 
> void
> f (C *p)
> {
>   p->f();
>   p->f();
> }
> ---
> 
> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> 
> _Z1fP1C:
> .LFB0:
>         .cfi_startproc
>         pushq   %rbx
>         .cfi_def_cfa_offset 16
>         .cfi_offset 3, -16
>         movq    (%rdi), %rax
>         movq    %rdi, %rbx
>         jmp     .LIND1
> .LIND0:
>         pushq   16(%rax)
>         jmp     __x86_indirect_thunk
> .LIND1:
>         call    .LIND0
>         movq    (%rbx), %rax
>         movq    %rbx, %rdi
>         popq    %rbx
>         .cfi_def_cfa_offset 8
>         movq    16(%rax), %rax
>         jmp     __x86_indirect_thunk_rax
>         .cfi_endproc
> 
> x86-64 is supposed to have asynchronous unwind tables by default, but
> there is nothing that reflects the change in the (relative) frame
> address after .LIND0.  That region really has to be moved outside of
> the .cfi_startproc/.cfi_endproc bracket.
> 
> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
> branch via register whenever -mindirect-branch= is used.  Now,
> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> 
> _Z1fP1C:
> .LFB0:
> 	.cfi_startproc
> 	pushq	%rbx
> 	.cfi_def_cfa_offset 16
> 	.cfi_offset 3, -16
> 	movq	(%rdi), %rax
> 	movq	%rdi, %rbx
> 	movq	16(%rax), %rax
> 	call	__x86_indirect_thunk_rax
> 	movq	(%rbx), %rax
> 	movq	%rbx, %rdi
> 	popq	%rbx
> 	.cfi_def_cfa_offset 8
> 	movq	16(%rax), %rax
> 	jmp	__x86_indirect_thunk_rax
> 	.cfi_endproc
> 
> so that "-mindirect-branch=thunk-extern" is equivalent to
> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
> used by Linux kernel.
> 
> gcc/
> 
> 	PR target/84039
> 	* config/i386/constraints.md (Bs): Replace
> 	ix86_indirect_branch_register with
> 	TARGET_INDIRECT_BRANCH_REGISTER.
> 	(Bw): Likewise.
> 	* config/i386/i386.md (indirect_jump): Likewise.
> 	(tablejump): Likewise.
> 	(*sibcall_memory): Likewise.
> 	(*sibcall_value_memory): Likewise.
> 	Peepholes of indirect call and jump via memory: Likewise.
> 	(*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER.
> 	(*sibcall_value_GOT_32): Likewise.
> 	* config/i386/i386.opt: Likewise.
> 	* config/i386/predicates.md (indirect_branch_operand): Likewise.
> 	(GOT_memory_operand): Likewise.
> 	(call_insn_operand): Likewise.
> 	(sibcall_insn_operand): Likewise.
> 	(GOT32_symbol_operand): Likewise.
> 	* config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.

OK,
thanks!
Honza
> 
> gcc/testsuite/
> 
> 	PR target/84039
> 	* gcc.target/i386/indirect-thunk-1.c: Updated.
> 	* gcc.target/i386/indirect-thunk-2.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-3.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-4.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-5.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-6.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-7.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-1.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-2.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-3.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-4.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-5.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-6.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-bnd-1.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-bnd-2.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-bnd-3.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-bnd-4.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-1.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-2.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-3.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-4.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-5.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-6.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-1.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-2.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-3.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-4.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-5.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-6.c: Likewise.
> 	* gcc.target/i386/indirect-thunk-inline-7.c: Likewise.
> 	* gcc.target/i386/ret-thunk-9.c: Likewise.
> 	* gcc.target/i386/ret-thunk-10.c: Likewise.
> 	* gcc.target/i386/ret-thunk-11.c: Likewise.
> 	* gcc.target/i386/ret-thunk-12.c: Likewise.
> 	* gcc.target/i386/ret-thunk-13.c: Likewise.
> 	* gcc.target/i386/ret-thunk-14.c: Likewise.
> 	* gcc.target/i386/ret-thunk-15.c: Likewise.
> ---
>  gcc/config/i386/constraints.md                     |  4 ++--
>  gcc/config/i386/i386.h                             |  4 ++++
>  gcc/config/i386/i386.md                            | 28 +++++++++++++---------
>  gcc/config/i386/predicates.md                      |  6 ++---
>  gcc/testsuite/gcc.target/i386/indirect-thunk-1.c   |  5 ++--
>  gcc/testsuite/gcc.target/i386/indirect-thunk-2.c   |  5 ++--
>  gcc/testsuite/gcc.target/i386/indirect-thunk-3.c   |  5 ++--
>  gcc/testsuite/gcc.target/i386/indirect-thunk-4.c   |  5 ++--
>  gcc/testsuite/gcc.target/i386/indirect-thunk-5.c   |  6 +++--
>  gcc/testsuite/gcc.target/i386/indirect-thunk-6.c   | 12 ++++++----
>  gcc/testsuite/gcc.target/i386/indirect-thunk-7.c   |  5 ++--
>  .../gcc.target/i386/indirect-thunk-attr-1.c        |  5 ++--
>  .../gcc.target/i386/indirect-thunk-attr-2.c        |  5 ++--
>  .../gcc.target/i386/indirect-thunk-attr-3.c        |  3 +--
>  .../gcc.target/i386/indirect-thunk-attr-4.c        |  3 +--
>  .../gcc.target/i386/indirect-thunk-attr-5.c        |  9 ++++---
>  .../gcc.target/i386/indirect-thunk-attr-6.c        |  9 ++++---
>  .../gcc.target/i386/indirect-thunk-attr-7.c        |  5 ++--
>  .../gcc.target/i386/indirect-thunk-bnd-1.c         |  6 ++---
>  .../gcc.target/i386/indirect-thunk-bnd-2.c         |  6 ++---
>  .../gcc.target/i386/indirect-thunk-bnd-3.c         |  5 ++--
>  .../gcc.target/i386/indirect-thunk-bnd-4.c         |  7 +++---
>  .../gcc.target/i386/indirect-thunk-extern-1.c      |  5 ++--
>  .../gcc.target/i386/indirect-thunk-extern-2.c      |  5 ++--
>  .../gcc.target/i386/indirect-thunk-extern-3.c      |  9 ++++---
>  .../gcc.target/i386/indirect-thunk-extern-4.c      |  6 ++---
>  .../gcc.target/i386/indirect-thunk-extern-5.c      |  6 +++--
>  .../gcc.target/i386/indirect-thunk-extern-6.c      |  8 +++----
>  .../gcc.target/i386/indirect-thunk-extern-7.c      |  5 ++--
>  .../gcc.target/i386/indirect-thunk-inline-1.c      |  2 +-
>  .../gcc.target/i386/indirect-thunk-inline-2.c      |  2 +-
>  .../gcc.target/i386/indirect-thunk-inline-3.c      |  2 +-
>  .../gcc.target/i386/indirect-thunk-inline-4.c      |  2 +-
>  .../gcc.target/i386/indirect-thunk-inline-5.c      |  3 ++-
>  .../gcc.target/i386/indirect-thunk-inline-6.c      |  3 ++-
>  .../gcc.target/i386/indirect-thunk-inline-7.c      |  4 ++--
>  gcc/testsuite/gcc.target/i386/ret-thunk-10.c       |  9 +++----
>  gcc/testsuite/gcc.target/i386/ret-thunk-11.c       |  9 +++----
>  gcc/testsuite/gcc.target/i386/ret-thunk-12.c       |  8 +++----
>  gcc/testsuite/gcc.target/i386/ret-thunk-13.c       |  5 ++--
>  gcc/testsuite/gcc.target/i386/ret-thunk-14.c       |  7 +++---
>  gcc/testsuite/gcc.target/i386/ret-thunk-15.c       |  7 +++---
>  gcc/testsuite/gcc.target/i386/ret-thunk-9.c        | 13 ++++------
>  43 files changed, 127 insertions(+), 141 deletions(-)
> 
> diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> index 664e906b311..d026968c4c9 100644
> --- a/gcc/config/i386/constraints.md
> +++ b/gcc/config/i386/constraints.md
> @@ -225,7 +225,7 @@
>  
>  (define_constraint "Bs"
>    "@internal Sibcall memory operand."
> -  (ior (and (not (match_test "ix86_indirect_branch_register"))
> +  (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
>  	    (not (match_test "TARGET_X32"))
>  	    (match_operand 0 "sibcall_memory_operand"))
>         (and (match_test "TARGET_X32 && Pmode == DImode")
> @@ -233,7 +233,7 @@
>  
>  (define_constraint "Bw"
>    "@internal Call memory operand."
> -  (ior (and (not (match_test "ix86_indirect_branch_register"))
> +  (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
>  	    (not (match_test "TARGET_X32"))
>  	    (match_operand 0 "memory_operand"))
>         (and (match_test "TARGET_X32 && Pmode == DImode")
> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
> index 9d864501d4f..6f3ae683d74 100644
> --- a/gcc/config/i386/i386.h
> +++ b/gcc/config/i386/i386.h
> @@ -2709,6 +2709,10 @@ extern void debug_dispatch_window (int);
>  #define TARGET_PREFER_AVX256	(TARGET_PREFER_AVX128 \
>  				 || prefer_vector_width_type == PVW_AVX256)
>  
> +#define TARGET_INDIRECT_BRANCH_REGISTER \
> +  (ix86_indirect_branch_register \
> +   || cfun->machine->indirect_branch_type != indirect_branch_keep)
> +
>  #define IX86_HLE_ACQUIRE (1 << 16)
>  #define IX86_HLE_RELEASE (1 << 17)
>  
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index f271278ed58..85e4b07cd0f 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -12311,7 +12311,7 @@
>    [(set (pc) (match_operand 0 "indirect_branch_operand"))]
>    ""
>  {
> -  if (TARGET_X32 || ix86_indirect_branch_register)
> +  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
>      operands[0] = convert_memory_address (word_mode, operands[0]);
>    cfun->machine->has_local_indirect_jump = true;
>  })
> @@ -12365,7 +12365,7 @@
>  					 OPTAB_DIRECT);
>      }
>  
> -  if (TARGET_X32 || ix86_indirect_branch_register)
> +  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
>      operands[0] = convert_memory_address (word_mode, operands[0]);
>    cfun->machine->has_local_indirect_jump = true;
>  })
> @@ -12595,7 +12595,10 @@
>  		     (match_operand:SI 0 "register_no_elim_operand" "U")
>  		     (match_operand:SI 1 "GOT32_symbol_operand"))))
>  	 (match_operand 2))]
> -  "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
> +  "!TARGET_MACHO
> +  && !TARGET_64BIT
> +  && !TARGET_INDIRECT_BRANCH_REGISTER
> +  && SIBLING_CALL_P (insn)"
>  {
>    rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
>    fnaddr = gen_const_mem (SImode, fnaddr);
> @@ -12614,7 +12617,7 @@
>    [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
>  	 (match_operand 1))
>     (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
> -  "!TARGET_X32 && !ix86_indirect_branch_register"
> +  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
>    "* return ix86_output_call_insn (insn, operands[0]);"
>    [(set_attr "type" "call")])
>  
> @@ -12624,7 +12627,7 @@
>     (call (mem:QI (match_dup 0))
>  	 (match_operand 3))]
>    "!TARGET_X32
> -   && !ix86_indirect_branch_register
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
>     && SIBLING_CALL_P (peep2_next_insn (1))
>     && !reg_mentioned_p (operands[0],
>  			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
> @@ -12639,7 +12642,7 @@
>     (call (mem:QI (match_dup 0))
>  	 (match_operand 3))]
>    "!TARGET_X32
> -   && !ix86_indirect_branch_register
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
>     && SIBLING_CALL_P (peep2_next_insn (2))
>     && !reg_mentioned_p (operands[0],
>  			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
> @@ -12737,7 +12740,7 @@
>          (match_operand:W 1 "memory_operand"))
>     (set (pc) (match_dup 0))]
>    "!TARGET_X32
> -   && !ix86_indirect_branch_register
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
>     && peep2_reg_dead_p (2, operands[0])"
>    [(set (pc) (match_dup 1))])
>  
> @@ -12798,7 +12801,10 @@
>  			  (match_operand:SI 1 "register_no_elim_operand" "U")
>  			  (match_operand:SI 2 "GOT32_symbol_operand"))))
>  	 (match_operand 3)))]
> -  "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
> +  "!TARGET_MACHO
> +   && !TARGET_64BIT
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
> +   && SIBLING_CALL_P (insn)"
>  {
>    rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
>    fnaddr = gen_const_mem (SImode, fnaddr);
> @@ -12819,7 +12825,7 @@
>   	(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
>  	      (match_operand 2)))
>     (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
> -  "!TARGET_X32 && !ix86_indirect_branch_register"
> +  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
>    "* return ix86_output_call_insn (insn, operands[1]);"
>    [(set_attr "type" "callv")])
>  
> @@ -12830,7 +12836,7 @@
>     (call (mem:QI (match_dup 0))
>  		 (match_operand 3)))]
>    "!TARGET_X32
> -   && !ix86_indirect_branch_register
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
>     && SIBLING_CALL_P (peep2_next_insn (1))
>     && !reg_mentioned_p (operands[0],
>  			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
> @@ -12847,7 +12853,7 @@
>  	(call (mem:QI (match_dup 0))
>  	      (match_operand 3)))]
>    "!TARGET_X32
> -   && !ix86_indirect_branch_register
> +   && !TARGET_INDIRECT_BRANCH_REGISTER
>     && SIBLING_CALL_P (peep2_next_insn (2))
>     && !reg_mentioned_p (operands[0],
>  			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
> diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
> index 2f2393b9e3e..f6cdc86fc5f 100644
> --- a/gcc/config/i386/predicates.md
> +++ b/gcc/config/i386/predicates.md
> @@ -665,7 +665,7 @@
>  ;; Test for a valid operand for indirect branch.
>  (define_predicate "indirect_branch_operand"
>    (ior (match_operand 0 "register_operand")
> -       (and (not (match_test "ix86_indirect_branch_register"))
> +       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
>  	    (not (match_test "TARGET_X32"))
>  	    (match_operand 0 "memory_operand"))))
>  
> @@ -709,7 +709,7 @@
>    (ior (match_test "constant_call_address_operand
>  		     (op, mode == VOIDmode ? mode : Pmode)")
>         (match_operand 0 "call_register_no_elim_operand")
> -       (and (not (match_test "ix86_indirect_branch_register"))
> +       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
>  	    (ior (and (not (match_test "TARGET_X32"))
>  		      (match_operand 0 "memory_operand"))
>  		 (and (match_test "TARGET_X32 && Pmode == DImode")
> @@ -720,7 +720,7 @@
>    (ior (match_test "constant_call_address_operand
>  		     (op, mode == VOIDmode ? mode : Pmode)")
>         (match_operand 0 "register_no_elim_operand")
> -       (and (not (match_test "ix86_indirect_branch_register"))
> +       (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER"))
>  	    (ior (and (not (match_test "TARGET_X32"))
>  		      (match_operand 0 "sibcall_memory_operand"))
>  		 (and (match_test "TARGET_X32 && Pmode == DImode")
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
> index 60d09881a99..6e94d2c4865 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-1.c
> @@ -11,9 +11,8 @@ male_indirect_jump (long offset)
>    dispatch(offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
> index aac75163794..3c467078964 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-2.c
> @@ -11,9 +11,8 @@ male_indirect_jump (long offset)
>    dispatch[offset](offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
> index dab7ac2ef25..e4c9b885d50 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-3.c
> @@ -12,9 +12,8 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
> index 44cc5f52f45..b22554ae282 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-4.c
> @@ -12,9 +12,8 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
> index fcaa18d10b7..fb26c005e80 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-5.c
> @@ -9,8 +9,10 @@ foo (void)
>    bar ();
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
> index 1490f5336ca..8bc45ff68ce 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-6.c
> @@ -10,9 +10,13 @@ foo (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
> +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 { target x32 } } } */
> +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
>  /* { dg-final { scan-assembler {\tlfence} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
> index 17c2d0faf88..3c72036dbaf 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-7.c
> @@ -35,9 +35,8 @@ bar (int i)
>      }
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
> index 9194ccf3cbc..7106407b83d 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-1.c
> @@ -14,9 +14,8 @@ male_indirect_jump (long offset)
>    dispatch(offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
> index e51f261a612..27c7e5b029b 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-2.c
> @@ -12,9 +12,8 @@ male_indirect_jump (long offset)
>    dispatch[offset](offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
> index 4aeec1833cd..89a2bac8403 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-3.c
> @@ -14,10 +14,9 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
>  /* { dg-final { scan-assembler {\tlfence} } } */
>  /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
> index ac0e5999f63..3eb83c3779a 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-4.c
> @@ -13,10 +13,9 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
>  /* { dg-final { scan-assembler {\tlfence} } } */
>  /* { dg-final { scan-assembler-not "__x86_indirect_thunk" } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
> index 573cf1ef09e..0098dd1133d 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-5.c
> @@ -14,9 +14,8 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
> +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
> index b2b37fc6e2e..ece8de15a4b 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-6.c
> @@ -13,9 +13,8 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
> +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
> index 4a43e199931..d53fc887dcc 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
> @@ -36,9 +36,8 @@ bar (int i)
>      }
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
> index ac84ab623fa..73d16baddc7 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-1.c
> @@ -10,9 +10,9 @@ foo (void)
>    dispatch (buf);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */
> +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "bnd ret" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
> index ce655e8be1c..856751ac224 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-2.c
> @@ -11,10 +11,8 @@ foo (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "pushq\[ \t\]%rax" { target x32 } } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */
>  /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "bnd ret" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
> index d34485a0010..42312f65588 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-3.c
> @@ -10,8 +10,9 @@ foo (void)
>    bar (buf);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd" } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */
> +/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk_bnd_rax" { target lp64 } } } */
> +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_eax" { target ia32 } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "bnd call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "bnd ret" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
> index a5fc4a23351..8850f2ffca4 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-bnd-4.c
> @@ -11,10 +11,9 @@ foo (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*__x86_indirect_thunk" } } */
> -/* { dg-final { scan-assembler "bnd jmp\[ \t\]*\.LIND" } } */
> -/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 2 } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" } } */
> +/* { dg-final { scan-assembler "bnd call\[ \t\]*__x86_indirect_thunk_bnd_(r|e)ax" } } */
> +/* { dg-final { scan-assembler-times "bnd call\[ \t\]*\.LIND" 1 } } */
>  /* { dg-final { scan-assembler "bnd ret" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
>  /* { dg-final { scan-assembler {\tlfence} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
> index 579441f250e..c09dd0afd2d 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-1.c
> @@ -11,9 +11,8 @@ male_indirect_jump (long offset)
>    dispatch(offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
> index c92e6f2b02d..826425a5115 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-2.c
> @@ -11,9 +11,8 @@ male_indirect_jump (long offset)
>    dispatch[offset](offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
> index d9964c25bbd..385626850a2 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-3.c
> @@ -12,9 +12,8 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> +/* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
> +/* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
> index d4dca4dc5fe..1ae49b137ca 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-4.c
> @@ -12,9 +12,7 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
> index 5c07e02df6a..53282390977 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-5.c
> @@ -9,8 +9,10 @@ foo (void)
>    bar ();
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
> index 3eb440693a0..8ae43482d0c 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-6.c
> @@ -10,8 +10,8 @@ foo (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> -/* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 1 } } */
> -/* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 1 } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
> index aece9383697..2b9a33e93dc 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
> @@ -35,9 +35,8 @@ bar (int i)
>      }
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
> index 3aba5e8c81f..869d9040838 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-1.c
> @@ -11,7 +11,7 @@ male_indirect_jump (long offset)
>    dispatch(offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
> index 0f0181d6672..c5c16ed8bd8 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-2.c
> @@ -11,7 +11,7 @@ male_indirect_jump (long offset)
>    dispatch[offset](offset);
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
> index 2eef6f35a75..4a63ebed8ab 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-3.c
> @@ -12,7 +12,7 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times {\tpause} 1 } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
> index e825a10f14c..a395ffca018 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-4.c
> @@ -12,7 +12,7 @@ male_indirect_jump (long offset)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?dispatch" { target { { ! x32 } && *-*-linux* } } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?dispatch" { target *-*-linux* } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times {\tpause} 1 } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
> index c6d77e10352..21cbfd39582 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-5.c
> @@ -9,7 +9,8 @@ foo (void)
>    bar ();
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
> index 6454827b780..d1300f18dc7 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-6.c
> @@ -10,7 +10,8 @@ foo (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" } } */
> +/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*bar@GOT" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*bar@GOT" { target { ! x32 } } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 2 } } */
>  /* { dg-final { scan-assembler-times {\tpause} 1 } } */
> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
> index c67066cf197..ea009245a58 100644
> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-inline-7.c
> @@ -35,8 +35,8 @@ bar (int i)
>      }
>  }
>  
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%(r|e)ax" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler {\tpause} } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
> index 6de9b8c9f4f..b245d21b002 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-10.c
> @@ -15,9 +15,6 @@ foo (void)
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
>  /* { dg-final { scan-assembler-times {\tpause} 2 } } */
>  /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } }  } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
> index 36598037541..ce0543e1181 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-11.c
> @@ -15,9 +15,6 @@ foo (void)
>  /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
> index 5fb1a4de776..3b0023a0a6d 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-12.c
> @@ -15,8 +15,6 @@ foo (void)
>  /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk:" { target { ! x32 } }  } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler "__x86_indirect_thunk_(r|e)ax:" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
> index fd5b41fdd3f..55f156c4376 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-13.c
> @@ -14,9 +14,8 @@ foo (void)
>  /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
>  /* { dg-final { scan-assembler-times {\tpause} 2 } } */
>  /* { dg-final { scan-assembler-times {\tlfence} 2 } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
>  /* { dg-final { scan-assembler-times "jmp\[ \t\]*\.LIND" 3 } } */
>  /* { dg-final { scan-assembler-times "call\[ \t\]*\.LIND" 3 } } */
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_indirect_thunk" } } */
> -/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler-not "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
> index d606373ead1..1c790436a53 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-14.c
> @@ -16,7 +16,6 @@ foo (void)
>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*__x86_return_thunk" } } */
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } }  } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
> index 2038644aa59..bc2bedf5a9c 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-15.c
> @@ -16,7 +16,6 @@ foo (void)
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler-times {\tpause} 1 } } */
>  /* { dg-final { scan-assembler-times {\tlfence} 1 } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target x32 } } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
> index d34dd4e6dc7..b75fc9219b0 100644
> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-9.c
> @@ -14,11 +14,8 @@ foo (void)
>  /* { dg-final { scan-assembler "jmp\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "call\[ \t\]*\.LIND" } } */
>  /* { dg-final { scan-assembler "__x86_indirect_thunk:" } } */
> -/* { dg-final { scan-assembler-times {\tpause} 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times {\tlfence} 1 { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler "push(?:l|q)\[ \t\]*_?bar" { target { { ! x32 } && *-*-linux* } } } } */
> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk" { target { ! x32 } } } } */
> -/* { dg-final { scan-assembler-times {\tpause} 2 { target { x32 } } } } */
> -/* { dg-final { scan-assembler-times {\tlfence} 2 { target { x32 } } } } */
> -/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" { target { x32 } } } } */
> -/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" { target x32 } } } */
> +/* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*_?bar" { target *-*-linux* } } } */
> +/* { dg-final { scan-assembler-times {\tpause} 2 } } */
> +/* { dg-final { scan-assembler-times {\tlfence} 2 } } */
> +/* { dg-final { scan-assembler "call\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
> +/* { dg-final { scan-assembler-not "pushq\[ \t\]%rax" } } */
> -- 
> 2.14.3
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-26 16:54           ` Jan Hubicka
@ 2018-02-27 12:49             ` H.J. Lu
  2018-02-27 13:10               ` Jan Hubicka
  0 siblings, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2018-02-27 12:49 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches

On Mon, Feb 26, 2018 at 8:54 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> On Mon, Feb 26, 2018 at 7:47 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
>> > Hi,
>> > my main concern about the patch is that we now have -mindirect-branch=thunk-extern
>> > which is intended to work well and is used by kernel, but we also have other modes
>> > that are documented and as such they should work but they may lead to invalid
>> > unwind info (or did I miss anything imporant here?).
>> > Why we can't fix the others as well?
>> >
>>
>> I took a closer look at my commit message.  It does leave an impression that
>> only  -mindirect-branch=thunk-extern is fixed.  But in fact, all
>> -mindirect-branch=
>> choices are fixed.
>
> I see, sorry for confussion!
>>
>> 1.  -mindirect-branch=thunk generates:
>>
>>        .cfi_startproc
>>         pushq   %rbx
>>         .cfi_def_cfa_offset 16
>>         .cfi_offset 3, -16
>>         movq    (%rdi), %rax
>>         movq    %rdi, %rbx
>>         movq    16(%rax), %rax
>>         call    __x86_indirect_thunk_rax
>>         movq    (%rbx), %rax
>>         movq    %rbx, %rdi
>>         popq    %rbx
>>         .cfi_def_cfa_offset 8
>>         movq    16(%rax), %rax
>>         jmp     __x86_indirect_thunk_rax
>>         .cfi_endproc
>>
>> 2.  -mindirect-branch=thunk-inline generates:
>>
>>        .cfi_startproc
>>         pushq   %rbx
>>         .cfi_def_cfa_offset 16
>>         .cfi_offset 3, -16
>>         movq    (%rdi), %rax
>>         movq    %rdi, %rbx
>>         movq    16(%rax), %rax
>>         jmp     .LIND1
>> .LIND0:
>>         call    .LIND3
>> .LIND2:
>>         pause
>>         lfence
>>         jmp     .LIND2
>> .LIND3:
>>         mov     %rax, (%rsp)
>>         ret
>> .LIND1:
>>         call    .LIND0
>>         movq    (%rbx), %rax
>>         movq    %rbx, %rdi
>>         popq    %rbx
>>         .cfi_def_cfa_offset 8
>>         movq    16(%rax), %rax
>>         call    .LIND5
>> .LIND4:
>>         pause
>>         lfence
>>         jmp     .LIND4
>> .LIND5:
>>         mov     %rax, (%rsp)
>>         ret
>>         .cfi_endproc
>>
>> I updated the commit message with
>>
>> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
>> branch via register whenever -mindirect-branch= is used.
>>
>> OK for trunk?
>>
>> Thanks.
>>
>> --
>> H.J.
>
>> From bd0672bd070da6fa4ff630540c1d87df3e8fdd53 Mon Sep 17 00:00:00 2001
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>> Date: Fri, 26 Jan 2018 15:54:25 -0800
>> Subject: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
>>
>> For
>>
>> ---
>> struct C {
>>   virtual ~C();
>>   virtual void f();
>> };
>>
>> void
>> f (C *p)
>> {
>>   p->f();
>>   p->f();
>> }
>> ---
>>
>> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>>
>> _Z1fP1C:
>> .LFB0:
>>         .cfi_startproc
>>         pushq   %rbx
>>         .cfi_def_cfa_offset 16
>>         .cfi_offset 3, -16
>>         movq    (%rdi), %rax
>>         movq    %rdi, %rbx
>>         jmp     .LIND1
>> .LIND0:
>>         pushq   16(%rax)
>>         jmp     __x86_indirect_thunk
>> .LIND1:
>>         call    .LIND0
>>         movq    (%rbx), %rax
>>         movq    %rbx, %rdi
>>         popq    %rbx
>>         .cfi_def_cfa_offset 8
>>         movq    16(%rax), %rax
>>         jmp     __x86_indirect_thunk_rax
>>         .cfi_endproc
>>
>> x86-64 is supposed to have asynchronous unwind tables by default, but
>> there is nothing that reflects the change in the (relative) frame
>> address after .LIND0.  That region really has to be moved outside of
>> the .cfi_startproc/.cfi_endproc bracket.
>>
>> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
>> branch via register whenever -mindirect-branch= is used.  Now,
>> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
>>
>> _Z1fP1C:
>> .LFB0:
>>       .cfi_startproc
>>       pushq   %rbx
>>       .cfi_def_cfa_offset 16
>>       .cfi_offset 3, -16
>>       movq    (%rdi), %rax
>>       movq    %rdi, %rbx
>>       movq    16(%rax), %rax
>>       call    __x86_indirect_thunk_rax
>>       movq    (%rbx), %rax
>>       movq    %rbx, %rdi
>>       popq    %rbx
>>       .cfi_def_cfa_offset 8
>>       movq    16(%rax), %rax
>>       jmp     __x86_indirect_thunk_rax
>>       .cfi_endproc
>>
>> so that "-mindirect-branch=thunk-extern" is equivalent to
>> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
>> used by Linux kernel.
>>
>> gcc/
>>
>>       PR target/84039
>>       * config/i386/constraints.md (Bs): Replace
>>       ix86_indirect_branch_register with
>>       TARGET_INDIRECT_BRANCH_REGISTER.
>>       (Bw): Likewise.
>>       * config/i386/i386.md (indirect_jump): Likewise.
>>       (tablejump): Likewise.
>>       (*sibcall_memory): Likewise.
>>       (*sibcall_value_memory): Likewise.
>>       Peepholes of indirect call and jump via memory: Likewise.
>>       (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER.
>>       (*sibcall_value_GOT_32): Likewise.
>>       * config/i386/i386.opt: Likewise.
>>       * config/i386/predicates.md (indirect_branch_operand): Likewise.
>>       (GOT_memory_operand): Likewise.
>>       (call_insn_operand): Likewise.
>>       (sibcall_insn_operand): Likewise.
>>       (GOT32_symbol_operand): Likewise.
>>       * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.
>
> OK,
> thanks!
> Honza

OK for backport to GCC 7 after a few days?

-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-27 12:49             ` H.J. Lu
@ 2018-02-27 13:10               ` Jan Hubicka
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Hubicka @ 2018-02-27 13:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GCC Patches

> On Mon, Feb 26, 2018 at 8:54 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> On Mon, Feb 26, 2018 at 7:47 AM, Jan Hubicka <hubicka@ucw.cz> wrote:
> >> > Hi,
> >> > my main concern about the patch is that we now have -mindirect-branch=thunk-extern
> >> > which is intended to work well and is used by kernel, but we also have other modes
> >> > that are documented and as such they should work but they may lead to invalid
> >> > unwind info (or did I miss anything imporant here?).
> >> > Why we can't fix the others as well?
> >> >
> >>
> >> I took a closer look at my commit message.  It does leave an impression that
> >> only  -mindirect-branch=thunk-extern is fixed.  But in fact, all
> >> -mindirect-branch=
> >> choices are fixed.
> >
> > I see, sorry for confussion!
> >>
> >> 1.  -mindirect-branch=thunk generates:
> >>
> >>        .cfi_startproc
> >>         pushq   %rbx
> >>         .cfi_def_cfa_offset 16
> >>         .cfi_offset 3, -16
> >>         movq    (%rdi), %rax
> >>         movq    %rdi, %rbx
> >>         movq    16(%rax), %rax
> >>         call    __x86_indirect_thunk_rax
> >>         movq    (%rbx), %rax
> >>         movq    %rbx, %rdi
> >>         popq    %rbx
> >>         .cfi_def_cfa_offset 8
> >>         movq    16(%rax), %rax
> >>         jmp     __x86_indirect_thunk_rax
> >>         .cfi_endproc
> >>
> >> 2.  -mindirect-branch=thunk-inline generates:
> >>
> >>        .cfi_startproc
> >>         pushq   %rbx
> >>         .cfi_def_cfa_offset 16
> >>         .cfi_offset 3, -16
> >>         movq    (%rdi), %rax
> >>         movq    %rdi, %rbx
> >>         movq    16(%rax), %rax
> >>         jmp     .LIND1
> >> .LIND0:
> >>         call    .LIND3
> >> .LIND2:
> >>         pause
> >>         lfence
> >>         jmp     .LIND2
> >> .LIND3:
> >>         mov     %rax, (%rsp)
> >>         ret
> >> .LIND1:
> >>         call    .LIND0
> >>         movq    (%rbx), %rax
> >>         movq    %rbx, %rdi
> >>         popq    %rbx
> >>         .cfi_def_cfa_offset 8
> >>         movq    16(%rax), %rax
> >>         call    .LIND5
> >> .LIND4:
> >>         pause
> >>         lfence
> >>         jmp     .LIND4
> >> .LIND5:
> >>         mov     %rax, (%rsp)
> >>         ret
> >>         .cfi_endproc
> >>
> >> I updated the commit message with
> >>
> >> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
> >> branch via register whenever -mindirect-branch= is used.
> >>
> >> OK for trunk?
> >>
> >> Thanks.
> >>
> >> --
> >> H.J.
> >
> >> From bd0672bd070da6fa4ff630540c1d87df3e8fdd53 Mon Sep 17 00:00:00 2001
> >> From: "H.J. Lu" <hjl.tools@gmail.com>
> >> Date: Fri, 26 Jan 2018 15:54:25 -0800
> >> Subject: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
> >>
> >> For
> >>
> >> ---
> >> struct C {
> >>   virtual ~C();
> >>   virtual void f();
> >> };
> >>
> >> void
> >> f (C *p)
> >> {
> >>   p->f();
> >>   p->f();
> >> }
> >> ---
> >>
> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> >>
> >> _Z1fP1C:
> >> .LFB0:
> >>         .cfi_startproc
> >>         pushq   %rbx
> >>         .cfi_def_cfa_offset 16
> >>         .cfi_offset 3, -16
> >>         movq    (%rdi), %rax
> >>         movq    %rdi, %rbx
> >>         jmp     .LIND1
> >> .LIND0:
> >>         pushq   16(%rax)
> >>         jmp     __x86_indirect_thunk
> >> .LIND1:
> >>         call    .LIND0
> >>         movq    (%rbx), %rax
> >>         movq    %rbx, %rdi
> >>         popq    %rbx
> >>         .cfi_def_cfa_offset 8
> >>         movq    16(%rax), %rax
> >>         jmp     __x86_indirect_thunk_rax
> >>         .cfi_endproc
> >>
> >> x86-64 is supposed to have asynchronous unwind tables by default, but
> >> there is nothing that reflects the change in the (relative) frame
> >> address after .LIND0.  That region really has to be moved outside of
> >> the .cfi_startproc/.cfi_endproc bracket.
> >>
> >> This patch adds TARGET_INDIRECT_BRANCH_REGISTER to force indirect
> >> branch via register whenever -mindirect-branch= is used.  Now,
> >> -mindirect-branch=thunk-extern -O2 on x86-64 GNU/Linux generates:
> >>
> >> _Z1fP1C:
> >> .LFB0:
> >>       .cfi_startproc
> >>       pushq   %rbx
> >>       .cfi_def_cfa_offset 16
> >>       .cfi_offset 3, -16
> >>       movq    (%rdi), %rax
> >>       movq    %rdi, %rbx
> >>       movq    16(%rax), %rax
> >>       call    __x86_indirect_thunk_rax
> >>       movq    (%rbx), %rax
> >>       movq    %rbx, %rdi
> >>       popq    %rbx
> >>       .cfi_def_cfa_offset 8
> >>       movq    16(%rax), %rax
> >>       jmp     __x86_indirect_thunk_rax
> >>       .cfi_endproc
> >>
> >> so that "-mindirect-branch=thunk-extern" is equivalent to
> >> "-mindirect-branch=thunk-extern -mindirect-branch-register", which is
> >> used by Linux kernel.
> >>
> >> gcc/
> >>
> >>       PR target/84039
> >>       * config/i386/constraints.md (Bs): Replace
> >>       ix86_indirect_branch_register with
> >>       TARGET_INDIRECT_BRANCH_REGISTER.
> >>       (Bw): Likewise.
> >>       * config/i386/i386.md (indirect_jump): Likewise.
> >>       (tablejump): Likewise.
> >>       (*sibcall_memory): Likewise.
> >>       (*sibcall_value_memory): Likewise.
> >>       Peepholes of indirect call and jump via memory: Likewise.
> >>       (*sibcall_GOT_32): Disallowed for TARGET_INDIRECT_BRANCH_REGISTER.
> >>       (*sibcall_value_GOT_32): Likewise.
> >>       * config/i386/i386.opt: Likewise.
> >>       * config/i386/predicates.md (indirect_branch_operand): Likewise.
> >>       (GOT_memory_operand): Likewise.
> >>       (call_insn_operand): Likewise.
> >>       (sibcall_insn_operand): Likewise.
> >>       (GOT32_symbol_operand): Likewise.
> >>       * config/i386/i386.h (TARGET_INDIRECT_BRANCH_REGISTER): New.
> >
> > OK,
> > thanks!
> > Honza
> 
> OK for backport to GCC 7 after a few days?
OK,
Honza
> 
> -- 
> H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-22 17:10       ` Jeff Law
  2018-02-22 17:33         ` H.J. Lu
@ 2018-02-28  9:39         ` Steve Beattie
  2018-02-28 15:58           ` Jeff Law
  1 sibling, 1 reply; 15+ messages in thread
From: Steve Beattie @ 2018-02-28  9:39 UTC (permalink / raw)
  To: Jeff Law; +Cc: Jan Hubicka, H.J. Lu, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1385 bytes --]

Hi Jeff,

On Thu, Feb 22, 2018 at 10:10:13AM -0700, Jeff Law wrote:
> A few notes.
> 
> 1. It's not even clear at this time that retpolining user space binaries
> makes any sense at all.   SO before doing anything to make this easier
> I'd like to see a justification for why it's really needed.

Do you have a reference that gives evidence that retpolining user
space is not needed or not preferred for x86? Everything that I've
seen has suggested user space to user space attacks are possible,
if difficult. And it does not seem likely that microcode updates will
occur for all processor generations out there.

> 2. On the other hand, the existing thunk options do make it easier to
> test independent of hte kernel.  ie, I can turn on inline thunks by
> default and test things in user space (ie, do thunks generally work
> properly).

If thunk-extern is to be the only maintained option, and its deemed
sensible for user space in at least some situations, is there a
preferred location for the thunks to end up?

(I ask these questions because you can already find individual users
recompiling apps important to them with retpoline options, and there
is pressure (with associated deadlines) in some quarters to rebuild
vast tracts of user space with retpolines for x86.)

Thanks.

-- 
Steve Beattie
<sbeattie@ubuntu.com>
http://NxNW.org/~steve/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER
  2018-02-28  9:39         ` Steve Beattie
@ 2018-02-28 15:58           ` Jeff Law
  0 siblings, 0 replies; 15+ messages in thread
From: Jeff Law @ 2018-02-28 15:58 UTC (permalink / raw)
  To: Steve Beattie; +Cc: Jan Hubicka, H.J. Lu, GCC Patches


[-- Attachment #1.1: Type: text/plain, Size: 2195 bytes --]

On 02/28/2018 02:39 AM, Steve Beattie wrote:
> Hi Jeff,
> 
> On Thu, Feb 22, 2018 at 10:10:13AM -0700, Jeff Law wrote:
>> A few notes.
>>
>> 1. It's not even clear at this time that retpolining user space binaries
>> makes any sense at all.   SO before doing anything to make this easier
>> I'd like to see a justification for why it's really needed.
> 
> Do you have a reference that gives evidence that retpolining user
> space is not needed or not preferred for x86? Everything that I've
> seen has suggested user space to user space attacks are possible,
> if difficult. And it does not seem likely that microcode updates will
> occur for all processor generations out there.
No reference, but that's general conclusion we've come to internally
with input from Intel.

Essentially you use the newly exposed capabilities from the microcode
updates to flush the state of the indirect predictor at context switch
time.  Combine that with the microcode change to stop sharing indirect
branch prediction state between SMT threads.

I'm being a bit imprecise, but that's the gist.


> 
>> 2. On the other hand, the existing thunk options do make it easier to
>> test independent of hte kernel.  ie, I can turn on inline thunks by
>> default and test things in user space (ie, do thunks generally work
>> properly).
> 
> If thunk-extern is to be the only maintained option, and its deemed
> sensible for user space in at least some situations, is there a
> preferred location for the thunks to end up?
Ideally you'd have one set of thunks per DSO.  Otherwise you end up
doing an indirect branch for the cross-DSO call to get to the thunk
which largely defeats the purpose of the thunks to begin with.


> 
> (I ask these questions because you can already find individual users
> recompiling apps important to them with retpoline options, and there
> is pressure (with associated deadlines) in some quarters to rebuild
> vast tracts of user space with retpolines for x86.)
I know.  I've given up trying to educate all of them.  I expected all
along that well intentioned, but ultimately clueless, folks would start
doing this kind of thing.

jeff


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-02-28 15:58 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-08 18:05 PING: [PATCH] i386: Add TARGET_INDIRECT_BRANCH_REGISTER H.J. Lu
2018-02-22 14:29 ` Jan Hubicka
2018-02-22 14:34   ` H.J. Lu
2018-02-22 14:38     ` Jan Hubicka
2018-02-22 16:34       ` H.J. Lu
2018-02-22 17:10       ` Jeff Law
2018-02-22 17:33         ` H.J. Lu
2018-02-23 20:53           ` H.J. Lu
2018-02-28  9:39         ` Steve Beattie
2018-02-28 15:58           ` Jeff Law
2018-02-26 15:47       ` Jan Hubicka
2018-02-26 16:22         ` H.J. Lu
2018-02-26 16:54           ` Jan Hubicka
2018-02-27 12:49             ` H.J. Lu
2018-02-27 13:10               ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).