-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.

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
      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"
 {
   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
   && 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

Reply via email to