i386: Don't generate alias for function return thunk
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 15 Mar 2018 17:54:40 +0000 (17:54 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 15 Mar 2018 17:54:40 +0000 (10:54 -0700)
Function return thunks shouldn't be aliased to indirect branch thunks
since indirect branch thunks are placed in COMDAT section and a COMDAT
section with indirect branch may not have function return thunk.  This
patch generates function return thunks directly.

gcc/

PR target/84574
* config/i386/i386.c (indirect_thunk_needed): Update comments.
(indirect_thunk_bnd_needed): Likewise.
(indirect_thunks_used): Likewise.
(indirect_thunks_bnd_used): Likewise.
(indirect_return_needed): New.
(indirect_return_bnd_needed): Likewise.
(output_indirect_thunk_function): Add a bool argument for
function return.
(output_indirect_thunk_function): Don't generate alias for
function return thunk.
(ix86_code_end): Call output_indirect_thunk_function to generate
function return thunks.
(ix86_output_function_return): Set indirect_return_bnd_needed
and indirect_return_needed instead of indirect_thunk_bnd_needed
and indirect_thunk_needed.

gcc/testsuite/

PR target/84574
* gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk
label instead of __x86_indirect_thunk label.

From-SVN: r258569

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/ret-thunk-9.c

index 69fc449326876f9e72c493003a8e84f5673a902a..1d0ab4e765eccd754d32aec9532494d9b92e6158 100644 (file)
@@ -1,3 +1,22 @@
+2018-03-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/84574
+       * config/i386/i386.c (indirect_thunk_needed): Update comments.
+       (indirect_thunk_bnd_needed): Likewise.
+       (indirect_thunks_used): Likewise.
+       (indirect_thunks_bnd_used): Likewise.
+       (indirect_return_needed): New.
+       (indirect_return_bnd_needed): Likewise.
+       (output_indirect_thunk_function): Add a bool argument for
+       function return.
+       (output_indirect_thunk_function): Don't generate alias for
+       function return thunk.
+       (ix86_code_end): Call output_indirect_thunk_function to generate
+       function return thunks.
+       (ix86_output_function_return): Set indirect_return_bnd_needed
+       and indirect_return_needed instead of indirect_thunk_bnd_needed
+       and indirect_thunk_needed.
+
 2018-03-15  Olga Makhotina  <olga.makhotina@intel.com>
 
        * config/i386/sgxintrin.h (_enclv_u32): New intrinsic.
index 1b57cc6c851b65e559ad19a9c2758ba64114d44f..00668b4413931a791611eecee4a3da548420f6e4 100644 (file)
@@ -10819,19 +10819,23 @@ ix86_setup_frame_addresses (void)
    labels in call and return thunks.  */
 static int indirectlabelno;
 
-/* True if call and return thunk functions are needed.  */
+/* True if call thunk function is needed.  */
 static bool indirect_thunk_needed = false;
-/* True if call and return thunk functions with the BND prefix are
-   needed.  */
+/* True if call thunk function with the BND prefix is needed.  */
 static bool indirect_thunk_bnd_needed = false;
 
 /* Bit masks of integer registers, which contain branch target, used
-   by call and return thunks functions.  */
+   by call thunk functions.  */
 static int indirect_thunks_used;
 /* Bit masks of integer registers, which contain branch target, used
-   by call and return thunks functions with the BND prefix.  */
+   by call thunk functions with the BND prefix.  */
 static int indirect_thunks_bnd_used;
 
+/* True if return thunk function is needed.  */
+static bool indirect_return_needed = false;
+/* True if return thunk function with the BND prefix is needed.  */
+static bool indirect_return_bnd_needed = false;
+
 /* True if return thunk function via CX is needed.  */
 static bool indirect_return_via_cx;
 /* True if return thunk function via CX with the BND prefix is
@@ -11027,17 +11031,18 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
 /* Output a funtion with a call and return thunk for indirect branch.
    If BND_P is true, the BND prefix is needed.  If REGNO != UNVALID_REGNUM,
    the function address is in REGNO.  Otherwise, the function address is
-   on the top of stack.  */
+   on the top of stack.  Thunk is used for function return if RET_P is
+   true.  */
 
 static void
 output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
-                               unsigned int regno)
+                               unsigned int regno, bool ret_p)
 {
   char name[32];
   tree decl;
 
   /* Create __x86_indirect_thunk/__x86_indirect_thunk_bnd.  */
-  indirect_thunk_name (name, regno, need_prefix, false);
+  indirect_thunk_name (name, regno, need_prefix, ret_p);
   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
                     get_identifier (name),
                     build_function_type_list (void_type_node, NULL_TREE));
@@ -11080,50 +11085,6 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
        ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
-  /* Create alias for __x86_return_thunk/__x86_return_thunk_bnd or
-     __x86_return_thunk_ecx/__x86_return_thunk_ecx_bnd.  */
-  bool need_alias;
-  if (regno == INVALID_REGNUM)
-    need_alias = true;
-  else if (regno == CX_REG)
-    {
-      if (need_prefix == indirect_thunk_prefix_bnd)
-       need_alias = indirect_return_via_cx_bnd;
-      else
-       need_alias = indirect_return_via_cx;
-    }
-  else
-    need_alias = false;
-
-  if (need_alias)
-    {
-      char alias[32];
-
-      indirect_thunk_name (alias, regno, need_prefix, true);
-#if TARGET_MACHO
-      if (TARGET_MACHO)
-       {
-         fputs ("\t.weak_definition\t", asm_out_file);
-         assemble_name (asm_out_file, alias);
-         fputs ("\n\t.private_extern\t", asm_out_file);
-         assemble_name (asm_out_file, alias);
-         putc ('\n', asm_out_file);
-         ASM_OUTPUT_LABEL (asm_out_file, alias);
-       }
-#else
-      ASM_OUTPUT_DEF (asm_out_file, alias, name);
-      if (USE_HIDDEN_LINKONCE)
-       {
-         fputs ("\t.globl\t", asm_out_file);
-         assemble_name (asm_out_file, alias);
-         putc ('\n', asm_out_file);
-         fputs ("\t.hidden\t", asm_out_file);
-         assemble_name (asm_out_file, alias);
-         putc ('\n', asm_out_file);
-       }
-#endif
-    }
-
   DECL_INITIAL (decl) = make_node (BLOCK);
   current_function_decl = decl;
   allocate_struct_function (decl, false);
@@ -11170,23 +11131,37 @@ ix86_code_end (void)
   rtx xops[2];
   unsigned int regno;
 
+  if (indirect_return_needed)
+    output_indirect_thunk_function (indirect_thunk_prefix_none,
+                                   INVALID_REGNUM, true);
+  if (indirect_return_bnd_needed)
+    output_indirect_thunk_function (indirect_thunk_prefix_bnd,
+                                   INVALID_REGNUM, true);
+
+  if (indirect_return_via_cx)
+    output_indirect_thunk_function (indirect_thunk_prefix_none,
+                                   CX_REG, true);
+  if (indirect_return_via_cx_bnd)
+    output_indirect_thunk_function (indirect_thunk_prefix_bnd,
+                                   CX_REG, true);
+
   if (indirect_thunk_needed)
     output_indirect_thunk_function (indirect_thunk_prefix_none,
-                                   INVALID_REGNUM);
+                                   INVALID_REGNUM, false);
   if (indirect_thunk_bnd_needed)
     output_indirect_thunk_function (indirect_thunk_prefix_bnd,
-                                   INVALID_REGNUM);
+                                   INVALID_REGNUM, false);
 
   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
     {
       unsigned int i = regno - FIRST_REX_INT_REG + LAST_INT_REG + 1;
       if ((indirect_thunks_used & (1 << i)))
        output_indirect_thunk_function (indirect_thunk_prefix_none,
-                                       regno);
+                                       regno, false);
 
       if ((indirect_thunks_bnd_used & (1 << i)))
        output_indirect_thunk_function (indirect_thunk_prefix_bnd,
-                                       regno);
+                                       regno, false);
     }
 
   for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
@@ -11196,11 +11171,11 @@ ix86_code_end (void)
 
       if ((indirect_thunks_used & (1 << regno)))
        output_indirect_thunk_function (indirect_thunk_prefix_none,
-                                       regno);
+                                       regno, false);
 
       if ((indirect_thunks_bnd_used & (1 << regno)))
        output_indirect_thunk_function (indirect_thunk_prefix_bnd,
-                                       regno);
+                                       regno, false);
 
       if (!(pic_labels_used & (1 << regno)))
        continue;
@@ -29060,12 +29035,12 @@ ix86_output_function_return (bool long_p)
                               true);
          if (need_prefix == indirect_thunk_prefix_bnd)
            {
-             indirect_thunk_bnd_needed |= need_thunk;
+             indirect_return_bnd_needed |= need_thunk;
              fprintf (asm_out_file, "\tbnd jmp\t%s\n", thunk_name);
            }
          else
            {
-             indirect_thunk_needed |= need_thunk;
+             indirect_return_needed |= need_thunk;
              fprintf (asm_out_file, "\tjmp\t%s\n", thunk_name);
            }
        }
index 56d931727b582640202c4bd197dd8a0fe27fdc9c..4b42ab735085311cb8cee13f4c3686ce7a4952c3 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/84574
+       * gcc.target/i386/ret-thunk-9.c: Expect __x86_return_thunk
+       label instead of __x86_indirect_thunk label.
+
 2018-03-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84222
index b75fc9219b017be7f9d7e3b8ac6aa143683bcfe5..819671af933cca66969bfd51bffec29d07263c16 100644 (file)
@@ -13,7 +13,7 @@ foo (void)
 /* { dg-final { scan-assembler "jmp\[ \t\]*__x86_return_thunk" } } */
 /* { 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 "__x86_return_thunk:" } } */
 /* { 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 } } */