Patchwork [i386] : Fix for PR/36834

login
register
mail settings
Submitter Kai Tietz
Date Dec. 15, 2010, 3:06 p.m.
Message ID <AANLkTinNAse2fduxAn+fC8v9XotJqd=5M3Q84U0LYin+@mail.gmail.com>
Download mbox | patch
Permalink /patch/75650/
State New
Headers show

Comments

Kai Tietz - Dec. 15, 2010, 3:06 p.m.
2010/12/14 NightStrike <nightstrike@gmail.com>:
> On Fri, Dec 3, 2010 at 6:31 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
>> Hello,
>>
>> this patch addresses described bug report at
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36834
>>
>> ChangeLog
>>
>> gcc/
>> 2010-12-03  Kai Tietz
>>
>>        PR target/36834
>>        * config/i386/i386.c (ix86_keep_aggregate_return_pointer):
>>        New local function.
>>        (ix86_return_pops_args): Use ix86_keep_aggregate_return_pointer
>>        function instead of KEEP_AGGREGATE_RETURN_POINTER.
>>        (ix86_handle_keep_aggregate_return_ptr_attrib): New handler.
>>        (ix86_attribute_table): Add new attributes
>>        dont_keep_aggregate_return_pointer and keep_aggregate_return_pointer.
>>        * doc/extend.texi (dont_keep_aggregate_return_pointer): Add
>>        attribute documentation.
>>        (keep_aggregate_return_pointer): Likewise.
>>
>> gcc/testsuite/
>> 2010-12-03  Kai Tietz
>>
>>        PR target/36834
>>        * gcc.target/i386/aggregate-ret1.c: New.
>>        * gcc.target/i386/aggregate-ret2.c: New.
>>
>> Tested for i686-w64-mingw32, x86_64-w64-mingw32, i686-pc-cygwin. Ok for apply?
>>
>> Regards,
>> Kai
>>
>
> Ping
>

I modified the patch - as discussed on IRC - so that we are using now
the attribute "callee_pop_aggregate_return" with an integer argument
of zero, or one allowed.

Tested for i686-pc-mingw32, i686-pc-cygwin. Ok for apply?

Kai
Richard Henderson - Dec. 17, 2010, 8:40 p.m.
> I modified the patch - as discussed on IRC - so that we are using now
> the attribute "callee_pop_aggregate_return" with an integer argument
> of zero, or one allowed.
> 
> Tested for i686-pc-mingw32, i686-pc-cygwin. Ok for apply?

Ok.


r~
Kai Tietz - Dec. 18, 2010, 10:17 a.m.
2010/12/17 Richard Henderson <rth@redhat.com>:
>> I modified the patch - as discussed on IRC - so that we are using now
>> the attribute "callee_pop_aggregate_return" with an integer argument
>> of zero, or one allowed.
>>
>> Tested for i686-pc-mingw32, i686-pc-cygwin. Ok for apply?
>
> Ok.
>
>
> r~
>

Applied at revision 168019.

Thanks,
Kai

Patch

Index: gcc/gcc/config/i386/i386.c
===================================================================
--- gcc.orig/gcc/config/i386/i386.c	2010-12-15 15:04:49.354121000 +0100
+++ gcc/gcc/config/i386/i386.c	2010-12-15 16:02:17.288642500 +0100
@@ -5433,6 +5433,19 @@  ix86_eax_live_at_start_p (void)
   return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR), 0);
 }
 
+static bool
+ix86_keep_aggregate_return_pointer (tree fntype)
+{
+  tree attr;
+
+  attr = lookup_attribute ("callee_pop_aggregate_return",
+			   TYPE_ATTRIBUTES (fntype));
+  if (attr)
+    return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
+
+  return KEEP_AGGREGATE_RETURN_POINTER != 0;
+}
+
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
    FUNDECL is the declaration node of the function (as a tree),
@@ -5477,7 +5490,7 @@  ix86_return_pops_args (tree fundecl, tre
 
   /* Lose any fake structure return argument if it is passed on the stack.  */
   if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
-      && !KEEP_AGGREGATE_RETURN_POINTER)
+      && !ix86_keep_aggregate_return_pointer (funtype))
     {
       int nregs = ix86_function_regparm (funtype, fundecl);
       if (nregs == 0)
@@ -29057,6 +29070,58 @@  x86_order_regs_for_local_alloc (void)
      reg_alloc_order [pos++] = 0;
 }
 
+/* Handle a "callee_pop_aggregate_return" attribute; arguments as
+   in struct attribute_spec handler.  */
+static tree
+ix86_handle_callee_pop_aggregate_return (tree *node, tree name,
+					      tree args,
+					      int flags ATTRIBUTE_UNUSED,
+					      bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_TYPE
+      && TREE_CODE (*node) != METHOD_TYPE
+      && TREE_CODE (*node) != FIELD_DECL
+      && TREE_CODE (*node) != TYPE_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute only applies to functions",
+	       name);
+      *no_add_attrs = true;
+      return NULL_TREE;
+    }
+  if (TARGET_64BIT)
+    {
+      warning (OPT_Wattributes, "%qE attribute only available for 32-bit",
+	       name);
+      *no_add_attrs = true;
+      return NULL_TREE;
+    }
+  if (is_attribute_p ("callee_pop_aggregate_return", name))
+    {
+      tree cst;
+
+      cst = TREE_VALUE (args);
+      if (TREE_CODE (cst) != INTEGER_CST)
+	{
+	  warning (OPT_Wattributes,
+		   "%qE attribute requires an integer constant argument",
+		   name);
+	  *no_add_attrs = true;
+	}
+      else if (compare_tree_int (cst, 0) != 0
+	       && compare_tree_int (cst, 1) != 0)
+	{
+	  warning (OPT_Wattributes,
+		   "argument to %qE attribute is neither zero, nor one",
+		   name);
+	  *no_add_attrs = true;
+	}
+
+      return NULL_TREE;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "ms_abi" or "sysv" attribute; arguments as in
    struct attribute_spec.handler.  */
 static tree
@@ -32226,6 +32291,8 @@  static const struct attribute_spec ix86_
   { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute },
+  { "callee_pop_aggregate_return", 1, 1, false, true, true,
+    ix86_handle_callee_pop_aggregate_return },
   /* End element.  */
   { NULL,        0, 0, false, false, false, NULL }
 };
Index: gcc/gcc/doc/extend.texi
===================================================================
--- gcc.orig/gcc/doc/extend.texi	2010-12-15 15:04:49.357121000 +0100
+++ gcc/gcc/doc/extend.texi	2010-12-15 15:16:03.666621600 +0100
@@ -2823,6 +2823,19 @@  when targeting Windows.  On all other sy
 Note, the @code{ms_abi} attribute for Windows targets currently requires
 the @option{-maccumulate-outgoing-args} option.
 
+@item callee_pop_aggregate_return (@var{number})
+@cindex @code{callee_pop_aggregate_return} attribute
+
+On 32-bit i?86-*-* targets, you can control by those attribute for
+aggregate return in memory, if the caller is responsible to pop the hidden
+pointer together with the rest of the arguments - @var{number} equal to
+zero -, or if the callee is responsible to pop hidden pointer - @var{number}
+equal to one.
+
+For i?86-netware, the caller pops the stack for the hidden arguments pointing
+to aggregate return value.  This differs from the default i386 ABI which assumes
+that the callee pops the stack for hidden pointer.
+
 @item ms_hook_prologue
 @cindex @code{ms_hook_prologue} attribute
 
Index: gcc/gcc/testsuite/gcc.target/i386/aggregate-ret1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/i386/aggregate-ret1.c	2010-12-15 15:08:46.150996600 +0100
@@ -0,0 +1,28 @@ 
+/* target/36834 */
+/* Check that, with keep_aggregate_return_pointer attribute,  callee does
+   not pop the stack for the implicit pointer arg when returning a large
+   structure in memory.  */
+/* { dg-do compile { target i?86-*-* } } */
+
+struct foo {
+  int a;
+  int b;
+  int c;
+  int d;
+};
+
+__attribute__ ((callee_pop_aggregate_return(0)))
+struct foo
+bar (void)
+{
+  struct foo retval;
+  retval.a = 1;
+  retval.b = 2;
+  retval.c = 3;
+  retval.d = 4;
+  return retval;
+}
+
+/* { dg-final { scan-assembler-not "ret\[ \t\]\\\$4" } } */
+
+
Index: gcc/gcc/testsuite/gcc.target/i386/aggregate-ret2.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/i386/aggregate-ret2.c	2010-12-15 15:08:46.166621600 +0100
@@ -0,0 +1,28 @@ 
+/* target/36834 */
+/* Check that, with dont_keep_aggregate_return_pointer attribute,  callee
+   pops the stack for the implicit pointer arg when returning a large
+   structure in memory.  */
+/* { dg-do compile { target i?86-*-* } } */
+
+struct foo {
+  int a;
+  int b;
+  int c;
+  int d;
+};
+
+__attribute__ ((callee_pop_aggregate_return(1)))
+struct foo
+bar (void)
+{
+  struct foo retval;
+  retval.a = 1;
+  retval.b = 2;
+  retval.c = 3;
+  retval.d = 4;
+  return retval;
+}
+
+/* { dg-final { scan-assembler "ret\[ \t\]\\\$4" } } */
+
+