On Fri, Jan 31, 2025 at 8:44 PM Uros Bizjak <ubiz...@gmail.com> wrote: > > On Fri, Jan 31, 2025 at 12:09 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > -mindirect-branch-register requires indirect call and jump via register. > > For -mindirect-branch-register, expanding indirect call via register and > > update call patterns and peepholes to disable indirect call via memory. > > I think the approach is wrong, we already have > TARGET_INDIRECT_BRANCH_REGISTER that includes > ix86_indirect_branch_register: > > #define TARGET_INDIRECT_BRANCH_REGISTER \ > (ix86_indirect_branch_register \ > || cfun->machine->indirect_branch_type != indirect_branch_keep) > > and: > > (define_constraint "Bs" > "@internal Sibcall memory operand." > (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") > (match_test "Pmode == DImode") > (match_operand 0 "GOT_memory_operand")))) > > (define_constraint "Bw" > "@internal Call memory operand." > (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) > (not (match_test "TARGET_X32")) > (match_operand 0 "memory_operand")) > (and (match_test "TARGET_X32") > (match_test "Pmode == DImode") > (match_operand 0 "GOT_memory_operand")))) > > So, the changes in the patch are mostly redundant, the remaining cases > should use TARGET_INDIRECT_BRANCH_REGISTER instead. > > Uros. > > > > > gcc/ > > > > PR target/115673 > > * config/i386/i386-expand.cc (ix86_expand_call): Force indirect > > call via register for -mindirect-branch-register. > > * config/i386/i386.md (*call): Disable indirect call via memory > > for -mindirect-branch-register. > > (*call_got_x32): Likewise. > > (*sibcall_GOT_32): Likewise. > > (*sibcall): Likewise. > > (*sibcall_memory): Likewise. > > (*call_pop): Likewise. > > (*sibcall_pop): Likewise. > > (*sibcall_pop_memory): Likewise. > > (*call_value): Likewise. > > (*call_value_got_x32): Likewise. > > (*sibcall_value_GOT_32): Likewise. > > (*sibcall_value): Likewise. > > (*sibcall_value_memory): Likewise. > > (*call_value_pop): Likewise. > > (*sibcall_value_pop): Likewise. > > (*sibcall_value_pop_memory): Likewise. > > Disable indirect call via memory peepholes for > > -mindirect-branch-register. > > > > gcc/testsuite/ > > > > PR target/115673 > > * gcc.target/i386/pr115673-1-x32.c: New test. > > * gcc.target/i386/pr115673-1.c: Likewise. > > * gcc.target/i386/pr115673-2-x32.c: Likewise. > > * gcc.target/i386/pr115673-2.c: Likewise. > > * gcc.target/i386/pr115673-3-x32.c: Likewise. > > * gcc.target/i386/pr115673-3.c: Likewise. > > * gcc.target/i386/pr115673-4-x32.c: Likewise. > > * gcc.target/i386/pr115673-4.c: Likewise. > > * gcc.target/i386/pr115673-5-x32.c: Likewise. > > * gcc.target/i386/pr115673-5.c: Likewise. > > * gcc.target/i386/pr115673-6-x32.c: Likewise. > > * gcc.target/i386/pr115673-6.c: Likewise. > > * gcc.target/i386/pr115673-7-x32.c: Likewise. > > * gcc.target/i386/pr115673-7.c: Likewise. > > * gcc.target/i386/pr115673-8-x32.c: Likewise. > > * gcc.target/i386/pr115673-8.c: Likewise. > > * gcc.target/i386/pr115673-9-x32.c: Likewise. > > * gcc.target/i386/pr115673-9.c: Likewise. > > * gcc.target/i386/pr115673-10-x32.c: Likewise. > > * gcc.target/i386/pr115673-10.c: Likewise. > > * gcc.target/i386/pr115673-11-x32.c: Likewise. > > * gcc.target/i386/pr115673-11.c: Likewise. > > * gcc.target/i386/pr115673-12-x32.c: Likewise. > > * gcc.target/i386/pr115673-12.c: Likewise. > > > > Co-Authored-By: Uros Bizjak <ubiz...@gmail.com> > > Signed-off-by: H.J. Lu <hjl.to...@gmail.com> > > --- > > gcc/config/i386/i386-expand.cc | 20 +-- > > gcc/config/i386/i386.md | 118 ++++++++++++------ > > .../gcc.target/i386/pr115673-1-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-1.c | 14 +++ > > .../gcc.target/i386/pr115673-10-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-10.c | 15 +++ > > .../gcc.target/i386/pr115673-11-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-11.c | 14 +++ > > .../gcc.target/i386/pr115673-12-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-12.c | 14 +++ > > .../gcc.target/i386/pr115673-2-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-2.c | 15 +++ > > .../gcc.target/i386/pr115673-3-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-3.c | 14 +++ > > .../gcc.target/i386/pr115673-4-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-4.c | 14 +++ > > .../gcc.target/i386/pr115673-5-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-5.c | 13 ++ > > .../gcc.target/i386/pr115673-6-x32.c | 15 +++ > > gcc/testsuite/gcc.target/i386/pr115673-6.c | 14 +++ > > .../gcc.target/i386/pr115673-7-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-7.c | 13 ++ > > .../gcc.target/i386/pr115673-8-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-8.c | 13 ++ > > .../gcc.target/i386/pr115673-9-x32.c | 8 ++ > > gcc/testsuite/gcc.target/i386/pr115673-9.c | 14 +++ > > 26 files changed, 365 insertions(+), 43 deletions(-) > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-1-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-1.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-10-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-10.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-11-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-11.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-12-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-12.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-2-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-2.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-3-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-3.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-4-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-4.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-5-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-5.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-6-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-6.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-7-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-7.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-8-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-8.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-9-x32.c > > create mode 100644 gcc/testsuite/gcc.target/i386/pr115673-9.c > > > > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc > > index 117f6f6f7eb..2fbb95aebaf 100644 > > --- a/gcc/config/i386/i386-expand.cc > > +++ b/gcc/config/i386/i386-expand.cc > > @@ -10223,15 +10223,21 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx > > callarg1, > > && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF > > && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) > > fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, > > 0))); > > + else if (ix86_indirect_branch_register && MEM_P (fnaddr)) > > + { > > + fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1); > > + fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr)); > > + } > > /* Since x32 GOT slot is 64 bit with zero upper 32 bits, indirect > > Probably only the above hunk is needed, but using > TARGET_INDIRECT_BRANCH_REGISTER.
Fixed. > > > branch via x32 GOT slot is OK. */ > > - else if (!(TARGET_X32 > > - && MEM_P (fnaddr) > > - && GET_CODE (XEXP (fnaddr, 0)) == ZERO_EXTEND > > - && GOT_memory_operand (XEXP (XEXP (fnaddr, 0), 0), Pmode)) > > - && (sibcall > > - ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) > > - : !call_insn_operand (XEXP (fnaddr, 0), word_mode))) > > + if (TARGET_X32 > > + && MEM_P (fnaddr) > > + && GET_CODE (XEXP (fnaddr, 0)) == ZERO_EXTEND > > + && GOT_memory_operand (XEXP (XEXP (fnaddr, 0), 0), Pmode)) > > + ; > > + else if (sibcall > > + ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) > > + : !call_insn_operand (XEXP (fnaddr, 0), word_mode)) > > { > > fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1); > > fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr)); > > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > > index 52c02b6351a..25b29947930 100644 > > --- a/gcc/config/i386/i386.md > > +++ b/gcc/config/i386/i386.md > > @@ -20122,18 +20122,23 @@ (define_expand "sibcall" > > }) > > > > (define_insn "*call" > > - [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) > > + [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>,BwBz")) > > (match_operand 1))] > > "!SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[0]);" > > - [(set_attr "type" "call")]) > > + [(set_attr "type" "call") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > ;; This covers both call and sibcall since only GOT slot is allowed. > > (define_insn "*call_got_x32" > > [(call (mem:QI (zero_extend:DI > > (match_operand:SI 0 "GOT_memory_operand" "Bg"))) > > (match_operand 1))] > > - "TARGET_X32" > > + "TARGET_X32 && !ix86_indirect_branch_register" > > This also needs !TARGET_INDIRECT_BRANCH_REGISTER. Fixed. > > { > > rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); > > return ix86_output_call_insn (insn, fnaddr); > > @@ -20149,7 +20154,7 @@ (define_insn "*sibcall_GOT_32" > > (match_operand:SI 1 "GOT32_symbol_operand")))) > > (match_operand 2))] > > "!TARGET_MACHO > > - && !TARGET_64BIT > > + && !TARGET_64BIT && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > !T_I_B_R is enough, it already includes ix86_indirect_branch_register. Dropped. > > && SIBLING_CALL_P (insn)" > > { > > @@ -20160,17 +20165,23 @@ (define_insn "*sibcall_GOT_32" > > [(set_attr "type" "call")]) > > > > (define_insn "*sibcall" > > - [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) > > + [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "U,BsBz")) > > (match_operand 1))] > > "SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[0]);" > > - [(set_attr "type" "call")]) > > + [(set_attr "type" "call") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_memory" > > [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) > > (match_operand 1)) > > (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > > - "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" > > + "!TARGET_X32 && !ix86_indirect_branch_register > > + && !TARGET_INDIRECT_BRANCH_REGISTER" > > "* return ix86_output_call_insn (insn, operands[0]);" > > [(set_attr "type" "call")]) > > > > @@ -20179,7 +20190,7 @@ (define_peephole2 > > (match_operand:W 1 "memory_operand")) > > (call (mem:QI (match_dup 0)) > > (match_operand 3))] > > - "!TARGET_X32 > > + "!TARGET_X32 && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > && SIBLING_CALL_P (peep2_next_insn (1)) > > && !reg_mentioned_p (operands[0], > > @@ -20194,7 +20205,7 @@ (define_peephole2 > > (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > > (call (mem:QI (match_dup 0)) > > (match_operand 3))] > > - "!TARGET_X32 > > + "!TARGET_X32 && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > && SIBLING_CALL_P (peep2_next_insn (2)) > > && !reg_mentioned_p (operands[0], > > @@ -20218,24 +20229,34 @@ (define_expand "call_pop" > > }) > > > > (define_insn "*call_pop" > > - [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) > > + [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "l,BwBz")) > > (match_operand 1)) > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > - (match_operand:SI 2 "immediate_operand" "i")))] > > + (match_operand:SI 2 "immediate_operand" "i,i")))] > > "!TARGET_64BIT && !SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[0]);" > > - [(set_attr "type" "call")]) > > + [(set_attr "type" "call") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_pop" > > - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) > > + [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "U,BsBz")) > > (match_operand 1)) > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > - (match_operand:SI 2 "immediate_operand" "i")))] > > + (match_operand:SI 2 "immediate_operand" "i,i")))] > > "!TARGET_64BIT && SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[0]);" > > - [(set_attr "type" "call")]) > > + [(set_attr "type" "call") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_pop_memory" > > [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) > > @@ -20244,7 +20265,7 @@ (define_insn "*sibcall_pop_memory" > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 2 "immediate_operand" "i"))) > > (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > > - "!TARGET_64BIT" > > + "!TARGET_64BIT && !ix86_indirect_branch_register" > > "* return ix86_output_call_insn (insn, operands[0]);" > > [(set_attr "type" "call")]) > > > > @@ -20256,7 +20277,8 @@ (define_peephole2 > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 4 "immediate_operand")))])] > > - "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) > > + "!TARGET_64BIT && !ix86_indirect_branch_register > > + && SIBLING_CALL_P (peep2_next_insn (1)) > > && !reg_mentioned_p (operands[0], > > CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" > > [(parallel [(call (mem:QI (match_dup 1)) > > @@ -20275,7 +20297,8 @@ (define_peephole2 > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 4 "immediate_operand")))])] > > - "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) > > + "!TARGET_64BIT && !ix86_indirect_branch_register > > + && SIBLING_CALL_P (peep2_next_insn (2)) > > && !reg_mentioned_p (operands[0], > > CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" > > [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > > @@ -20325,11 +20348,16 @@ (define_expand "sibcall_value" > > > > (define_insn "*call_value" > > [(set (match_operand 0) > > - (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) > > + (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>,BwBz")) > > (match_operand 2)))] > > "!SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[1]);" > > - [(set_attr "type" "callv")]) > > + [(set_attr "type" "callv") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > ;; This covers both call and sibcall since only GOT slot is allowed. > > (define_insn "*call_value_got_x32" > > @@ -20338,7 +20366,7 @@ (define_insn "*call_value_got_x32" > > (zero_extend:DI > > (match_operand:SI 1 "GOT_memory_operand" "Bg"))) > > (match_operand 2)))] > > - "TARGET_X32" > > + "TARGET_X32 && !ix86_indirect_branch_register" > > { > > rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); > > return ix86_output_call_insn (insn, fnaddr); > > @@ -20355,7 +20383,7 @@ (define_insn "*sibcall_value_GOT_32" > > (match_operand:SI 2 "GOT32_symbol_operand")))) > > (match_operand 3)))] > > "!TARGET_MACHO > > - && !TARGET_64BIT > > + && !TARGET_64BIT && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > && SIBLING_CALL_P (insn)" > > { > > @@ -20367,18 +20395,24 @@ (define_insn "*sibcall_value_GOT_32" > > > > (define_insn "*sibcall_value" > > [(set (match_operand 0) > > - (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) > > + (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "U,BsBz")) > > (match_operand 2)))] > > "SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[1]);" > > - [(set_attr "type" "callv")]) > > + [(set_attr "type" "callv") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_value_memory" > > [(set (match_operand 0) > > (call (mem:QI (match_operand:W 1 "memory_operand" "m")) > > (match_operand 2))) > > (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > > - "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" > > + "!TARGET_X32 && !ix86_indirect_branch_register > > + && !TARGET_INDIRECT_BRANCH_REGISTER" > > "* return ix86_output_call_insn (insn, operands[1]);" > > [(set_attr "type" "callv")]) > > > > @@ -20388,7 +20422,7 @@ (define_peephole2 > > (set (match_operand 2) > > (call (mem:QI (match_dup 0)) > > (match_operand 3)))] > > - "!TARGET_X32 > > + "!TARGET_X32 && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > && SIBLING_CALL_P (peep2_next_insn (1)) > > && !reg_mentioned_p (operands[0], > > @@ -20405,7 +20439,7 @@ (define_peephole2 > > (set (match_operand 2) > > (call (mem:QI (match_dup 0)) > > (match_operand 3)))] > > - "!TARGET_X32 > > + "!TARGET_X32 && !ix86_indirect_branch_register > > && !TARGET_INDIRECT_BRANCH_REGISTER > > && SIBLING_CALL_P (peep2_next_insn (2)) > > && !reg_mentioned_p (operands[0], > > @@ -20432,25 +20466,35 @@ (define_expand "call_value_pop" > > > > (define_insn "*call_value_pop" > > [(set (match_operand 0) > > - (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) > > + (call (mem:QI (match_operand:SI 1 "call_insn_operand" "l,BwBz")) > > (match_operand 2))) > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > - (match_operand:SI 3 "immediate_operand" "i")))] > > + (match_operand:SI 3 "immediate_operand" "i,i")))] > > "!TARGET_64BIT && !SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[1]);" > > - [(set_attr "type" "callv")]) > > + [(set_attr "type" "callv") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_value_pop" > > [(set (match_operand 0) > > - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) > > + (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "U,BsBz")) > > (match_operand 2))) > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > - (match_operand:SI 3 "immediate_operand" "i")))] > > + (match_operand:SI 3 "immediate_operand" "i,i")))] > > "!TARGET_64BIT && SIBLING_CALL_P (insn)" > > "* return ix86_output_call_insn (insn, operands[1]);" > > - [(set_attr "type" "callv")]) > > + [(set_attr "type" "callv") > > + (set (attr "enabled") > > + (if_then_else > > + (eq_attr "alternative" "1") > > + (symbol_ref "!ix86_indirect_branch_register") > > + (const_string "*")))]) > > > > (define_insn "*sibcall_value_pop_memory" > > [(set (match_operand 0) > > @@ -20460,7 +20504,7 @@ (define_insn "*sibcall_value_pop_memory" > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 3 "immediate_operand" "i"))) > > (unspec [(const_int 0)] UNSPEC_PEEPSIB)] > > - "!TARGET_64BIT" > > + "!TARGET_64BIT && !ix86_indirect_branch_register" > > "* return ix86_output_call_insn (insn, operands[1]);" > > [(set_attr "type" "callv")]) > > > > @@ -20473,7 +20517,8 @@ (define_peephole2 > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 4 "immediate_operand")))])] > > - "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) > > + "!TARGET_64BIT && !ix86_indirect_branch_register > > + && SIBLING_CALL_P (peep2_next_insn (1)) > > && !reg_mentioned_p (operands[0], > > CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" > > [(parallel [(set (match_dup 2) > > @@ -20494,7 +20539,8 @@ (define_peephole2 > > (set (reg:SI SP_REG) > > (plus:SI (reg:SI SP_REG) > > (match_operand:SI 4 "immediate_operand")))])] > > - "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) > > + "!TARGET_64BIT && !ix86_indirect_branch_register > > + && SIBLING_CALL_P (peep2_next_insn (2)) > > && !reg_mentioned_p (operands[0], > > CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" > > [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-1-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-1-x32.c > > new file mode 100644 > > index 00000000000..a727e92adbe > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-1-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +#include "pr115673-1.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-1.c > > b/gcc/testsuite/gcc.target/i386/pr115673-1.c > > new file mode 100644 > > index 00000000000..56884f3d952 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-1.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void); > > + > > +void > > +foo (void) > > +{ > > + bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT\\(" { target ia32 } } > > } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-10-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-10-x32.c > > new file mode 100644 > > index 00000000000..3249f2d251b > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-10-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-10.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-10.c > > b/gcc/testsuite/gcc.target/i386/pr115673-10.c > > new file mode 100644 > > index 00000000000..a0e2ff3760b > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-10.c > > @@ -0,0 +1,15 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void); > > + > > +int > > +foo (void) > > +{ > > + bar (); > > + return 0; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT, " { target ia32 } } } > > */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-11-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-11-x32.c > > new file mode 100644 > > index 00000000000..74f18737b3c > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-11-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-11.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-11.c > > b/gcc/testsuite/gcc.target/i386/pr115673-11.c > > new file mode 100644 > > index 00000000000..deb0c0df3c7 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-11.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void); > > + > > +int > > +foo (void) > > +{ > > + return bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT, " { target ia32 } } } > > */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-12-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-12-x32.c > > new file mode 100644 > > index 00000000000..1cf5be6ed95 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-12-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-12.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-12.c > > b/gcc/testsuite/gcc.target/i386/pr115673-12.c > > new file mode 100644 > > index 00000000000..333b9c813e5 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-12.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void); > > + > > +int > > +foo (void) > > +{ > > + return bar () + 1; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT, " { target ia32 } } } > > */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-2-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-2-x32.c > > new file mode 100644 > > index 00000000000..40ca0be4d12 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-2-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +#include "pr115673-2.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-2.c > > b/gcc/testsuite/gcc.target/i386/pr115673-2.c > > new file mode 100644 > > index 00000000000..807724e0310 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-2.c > > @@ -0,0 +1,15 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void); > > + > > +int > > +foo (void) > > +{ > > + bar (); > > + return 0; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT\\(" { target ia32 } } > > } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-3-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-3-x32.c > > new file mode 100644 > > index 00000000000..d80543e4c15 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-3-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +#include "pr115673-3.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-3.c > > b/gcc/testsuite/gcc.target/i386/pr115673-3.c > > new file mode 100644 > > index 00000000000..1cd3fcbdf66 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-3.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void); > > + > > +int > > +foo (void) > > +{ > > + return bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT\\(" { target ia32 } } > > } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-4-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-4-x32.c > > new file mode 100644 > > index 00000000000..bfb5b8accd6 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-4-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +#include "pr115673-4.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-4.c > > b/gcc/testsuite/gcc.target/i386/pr115673-4.c > > new file mode 100644 > > index 00000000000..86d13b73bfc > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-4.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fpic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void); > > + > > +int > > +foo (void) > > +{ > > + return bar () + 1; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT\\(" { target ia32 } } > > } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-5-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-5-x32.c > > new file mode 100644 > > index 00000000000..65d52447a1a > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-5-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-5.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-5.c > > b/gcc/testsuite/gcc.target/i386/pr115673-5.c > > new file mode 100644 > > index 00000000000..7b1f8c17c2d > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-5.c > > @@ -0,0 +1,13 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void) __attribute__((visibility("hidden"))); > > + > > +void > > +foo (void) > > +{ > > + bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-6-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-6-x32.c > > new file mode 100644 > > index 00000000000..f728b15db77 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-6-x32.c > > @@ -0,0 +1,15 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +extern void bar (void) __attribute__((visibility("hidden"))); > > + > > +int > > +foo (void) > > +{ > > + bar (); > > + return 0; > > +} > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-6.c > > b/gcc/testsuite/gcc.target/i386/pr115673-6.c > > new file mode 100644 > > index 00000000000..a4f3b68f3e7 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-6.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void) __attribute__((visibility("hidden"))); > > + > > +int > > +foo (void) > > +{ > > + bar (); > > + return 0; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-7-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-7-x32.c > > new file mode 100644 > > index 00000000000..084d8125b71 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-7-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-7.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-7.c > > b/gcc/testsuite/gcc.target/i386/pr115673-7.c > > new file mode 100644 > > index 00000000000..fdc0db951bf > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-7.c > > @@ -0,0 +1,13 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void) __attribute__((visibility("hidden"))); > > + > > +int > > +foo (void) > > +{ > > + return bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-8-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-8-x32.c > > new file mode 100644 > > index 00000000000..23c0bf5ad80 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-8-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-8.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-8.c > > b/gcc/testsuite/gcc.target/i386/pr115673-8.c > > new file mode 100644 > > index 00000000000..03d5f008e0d > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-8.c > > @@ -0,0 +1,13 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern int bar (void) __attribute__((visibility("hidden"))); > > + > > +int > > +foo (void) > > +{ > > + return bar () + 1; > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*\\\$bar, " } } */ > > +/* { dg-final { scan-assembler "call\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-9-x32.c > > b/gcc/testsuite/gcc.target/i386/pr115673-9-x32.c > > new file mode 100644 > > index 00000000000..f4370772ec1 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-9-x32.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-require-effective-target maybe_x32 } */ > > +/* { dg-options "-O2 -mx32 -fno-pic -fno-plt -mindirect-branch-register" } > > */ > > + > > +#include "pr115673-9.c" > > + > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOTPCREL" } } */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/pr115673-9.c > > b/gcc/testsuite/gcc.target/i386/pr115673-9.c > > new file mode 100644 > > index 00000000000..365f65fb194 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/pr115673-9.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile { target *-*-linux* } } */ > > +/* { dg-options "-O2 -fno-pic -fno-plt -mindirect-branch-register" } */ > > + > > +extern void bar (void); > > + > > +void > > +foo (void) > > +{ > > + bar (); > > +} > > + > > +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { > > ! ia32 } } } } */ > > +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT, " { target ia32 } } } > > */ > > +/* { dg-final { scan-assembler "jmp\[ \t\]*\\*%" } } */ > > -- > > 2.48.1 > > -- H.J.