* [patch i386]: Fix for PR/36834
@ 2010-12-03 11:31 Kai Tietz
2010-12-14 16:47 ` NightStrike
0 siblings, 1 reply; 5+ messages in thread
From: Kai Tietz @ 2010-12-03 11:31 UTC (permalink / raw)
To: GCC Patches; +Cc: Richard Henderson
[-- Attachment #1: Type: text/plain, Size: 900 bytes --]
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
[-- Attachment #2: pr36834.txt --]
[-- Type: text/plain, Size: 6515 bytes --]
Index: gcc/gcc/config/i386/i386.c
===================================================================
--- gcc.orig/gcc/config/i386/i386.c 2010-12-03 10:12:09.000000000 +0100
+++ gcc/gcc/config/i386/i386.c 2010-12-03 11:54:08.811957100 +0100
@@ -5428,6 +5428,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)
+{
+ if (lookup_attribute ("keep_aggregate_return_pointer",
+ TYPE_ATTRIBUTES (fntype)))
+ return true;
+ if (lookup_attribute ("dont_keep_aggregate_return_pointer",
+ TYPE_ATTRIBUTES (fntype)))
+ return false;
+
+ 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),
@@ -5472,7 +5485,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)
@@ -29052,6 +29065,59 @@ x86_order_regs_for_local_alloc (void)
reg_alloc_order [pos++] = 0;
}
+/* Handle a "dont_keep_aggregate_return_pointer" or
+ "keep_aggregate_return_pointer" attribut; arguments as
+ in struct attribute_spec handler. */
+static tree
+ix86_handle_keep_aggregate_return_ptr_attrib (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ 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 ("dont_keep_aggregate_return_pointer", name))
+ {
+ if (lookup_attribute ("keep_aggregate_return_pointer",
+ TYPE_ATTRIBUTES (*node)))
+ {
+ error ("dont_keep_aggregate_return_pointer and "
+ "keep_aggregate_return_pointer attributes "
+ "are not compatible");
+ }
+ return NULL_TREE;
+ }
+ else if (is_attribute_p ("keep_aggregate_return_pointer", name))
+ {
+ if (lookup_attribute ("dont_keep_aggregate_return_pointer",
+ TYPE_ATTRIBUTES (*node)))
+ {
+ error ("keep_aggregate_return_pointer and "
+ "dont_keep_aggregate_return_pointer attributes "
+ "are not compatible");
+ }
+
+ return NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "ms_abi" or "sysv" attribute; arguments as in
struct attribute_spec.handler. */
static tree
@@ -32221,6 +32287,10 @@ 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 },
+ { "dont_keep_aggregate_return_pointer", 0, 0, false, true, true,
+ ix86_handle_keep_aggregate_return_ptr_attrib },
+ { "keep_aggregate_return_pointer", 0, 0, false, true, true,
+ ix86_handle_keep_aggregate_return_ptr_attrib },
/* End element. */
{ NULL, 0, 0, false, false, false, NULL }
};
Index: gcc/gcc/doc/extend.texi
===================================================================
--- gcc.orig/gcc/doc/extend.texi 2010-11-22 14:41:40.000000000 +0100
+++ gcc/gcc/doc/extend.texi 2010-12-03 12:20:06.487884300 +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 dont_keep_aggregate_return_pointer/keep_aggregate_return_pointer
+@cindex @code{dont_keep_aggregate_return_pointer} attribute
+@cindex @code{keep_aggregate_return_pointer} attribute
+
+On 32-bit i?86-*-* targets, you can control by those attributes for
+aggregate return in memory, if the caller is responsible to pop the hidden
+pointer together with the rest of the arguments, or if the callee is responsible
+to pop hidden pointer.
+
+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-03 12:04:11.558266500 +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__ ((keep_aggregate_return_pointer))
+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-03 12:07:19.688082500 +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__ ((dont_keep_aggregate_return_pointer))
+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" } } */
+
+
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch i386]: Fix for PR/36834
2010-12-03 11:31 [patch i386]: Fix for PR/36834 Kai Tietz
@ 2010-12-14 16:47 ` NightStrike
2010-12-15 15:54 ` Kai Tietz
0 siblings, 1 reply; 5+ messages in thread
From: NightStrike @ 2010-12-14 16:47 UTC (permalink / raw)
To: Kai Tietz; +Cc: GCC Patches, Richard Henderson
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch i386]: Fix for PR/36834
2010-12-14 16:47 ` NightStrike
@ 2010-12-15 15:54 ` Kai Tietz
2010-12-17 20:59 ` Richard Henderson
0 siblings, 1 reply; 5+ messages in thread
From: Kai Tietz @ 2010-12-15 15:54 UTC (permalink / raw)
To: NightStrike; +Cc: GCC Patches, Richard Henderson
[-- Attachment #1: Type: text/plain, Size: 1619 bytes --]
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
--
| (\_/) This is Bunny. Copy and paste
| (='.'=) Bunny into your signature to help
| (")_(") him gain world domination
[-- Attachment #2: pr36834.txt --]
[-- Type: text/plain, Size: 6123 bytes --]
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" } } */
+
+
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch i386]: Fix for PR/36834
2010-12-15 15:54 ` Kai Tietz
@ 2010-12-17 20:59 ` Richard Henderson
2010-12-18 11:47 ` Kai Tietz
0 siblings, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2010-12-17 20:59 UTC (permalink / raw)
To: Kai Tietz; +Cc: NightStrike, GCC Patches
> 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~
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [patch i386]: Fix for PR/36834
2010-12-17 20:59 ` Richard Henderson
@ 2010-12-18 11:47 ` Kai Tietz
0 siblings, 0 replies; 5+ messages in thread
From: Kai Tietz @ 2010-12-18 11:47 UTC (permalink / raw)
To: Richard Henderson; +Cc: NightStrike, GCC Patches
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
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-12-18 10:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-03 11:31 [patch i386]: Fix for PR/36834 Kai Tietz
2010-12-14 16:47 ` NightStrike
2010-12-15 15:54 ` Kai Tietz
2010-12-17 20:59 ` Richard Henderson
2010-12-18 11:47 ` Kai Tietz
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).