aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorJosh Conner <jconner@apple.com>2007-07-06 16:57:19 +0000
committerJosh Conner <jconner@gcc.gnu.org>2007-07-06 16:57:19 +0000
commitd6c2c77c91822a5c3c215187d148bbc75d08751b (patch)
tree8514e0658aa1d573c48ff13021ae810fdecfcc38 /gcc/calls.c
parentbb9d1da7db4487a5aa836a0d5a39df8751201d25 (diff)
downloadgcc-d6c2c77c91822a5c3c215187d148bbc75d08751b.zip
gcc-d6c2c77c91822a5c3c215187d148bbc75d08751b.tar.gz
gcc-d6c2c77c91822a5c3c215187d148bbc75d08751b.tar.bz2
re PR middle-end/32602 (Sibcall optimization fails to detect overlap)
2007-07-06 Josh Conner <jconner@apple.com> PR middle-end/32602 PR middle-end/32603 * calls.c (store_one_arg): Handle arguments which are partially on the stack when detecting argument overlap. 2007-07-06 Josh Conner <jconner@apple.com> PR middle-end/32602 * gcc.dg/sibcall-8.c: New test. 2007-07-06 Josh Conner <jconner@apple.com> PR middle-end/32603 * gcc.target/arm/sibcall-1.c: New test. From-SVN: r126422
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index aa63755..e6741c8 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -4326,6 +4326,7 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
/* expand_call should ensure this. */
gcc_assert (!arg->locate.offset.var
+ && arg->locate.size.var == 0
&& GET_CODE (size_rtx) == CONST_INT);
if (arg->locate.offset.constant > i)
@@ -4335,7 +4336,21 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
}
else if (arg->locate.offset.constant < i)
{
- if (i < arg->locate.offset.constant + INTVAL (size_rtx))
+ /* Use arg->locate.size.constant instead of size_rtx
+ because we only care about the part of the argument
+ on the stack. */
+ if (i < (arg->locate.offset.constant
+ + arg->locate.size.constant))
+ sibcall_failure = 1;
+ }
+ else
+ {
+ /* Even though they appear to be at the same location,
+ if part of the outgoing argument is in registers,
+ they aren't really at the same location. Check for
+ this by making sure that the incoming size is the
+ same as the outgoing size. */
+ if (arg->locate.size.constant != INTVAL (size_rtx))
sibcall_failure = 1;
}
}