summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-26 09:58:28 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2015-11-26 09:58:28 +0000
commitc62f411b3c564e3bc2e231ec8fb8072c23a0a785 (patch)
tree2eccc3d73bf8aaf67a16ef370aea53376e5e186a
parente2225bd419ce30e32adc080be8cfe407d649fc95 (diff)
downloadgcc-c62f411b3c564e3bc2e231ec8fb8072c23a0a785.tar.gz
[calls.c] PR rtl-optimization/67226: Take into account pretend_args_size when checking stack offsets for sibcall optimisation
2015-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com> Bernd Schmidt <bschmidt@redhat.com> PR rtl-optimization/67226 * calls.c (store_one_arg): Take into account crtl->args.pretend_args_size when checking for overlap between arg->value and argblock + arg->locate.offset during sibcall optimization. * gcc.c-torture/execute/pr67226.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230929 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/calls.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr67226.c42
4 files changed, 63 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 56dd588c52e..58b789b81d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2015-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/67226
+ * calls.c (store_one_arg): Take into account
+ crtl->args.pretend_args_size when checking for overlap between
+ arg->value and argblock + arg->locate.offset during sibcall
+ optimization.
+
2015-11-26 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.md (cbranch<mode>4): Use
diff --git a/gcc/calls.c b/gcc/calls.c
index b56556a9d0a..6cbe01970c1 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -4939,6 +4939,13 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
if (XEXP (x, 0) != crtl->args.internal_arg_pointer)
i = INTVAL (XEXP (XEXP (x, 0), 1));
+ /* arg.locate doesn't contain the pretend_args_size offset,
+ it's part of argblock. Ensure we don't count it in I. */
+ if (STACK_GROWS_DOWNWARD)
+ i -= crtl->args.pretend_args_size;
+ else
+ i += crtl->args.pretend_args_size;
+
/* expand_call should ensure this. */
gcc_assert (!arg->locate.offset.var
&& arg->locate.size.var == 0
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2e9f9623db8..a1466e398aa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR rtl-optimization/67226
+ * gcc.c-torture/execute/pr67226.c: New test.
+
2015-11-26 Jakub Jelinek <jakub@redhat.com>
PR c++/68508
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr67226.c b/gcc/testsuite/gcc.c-torture/execute/pr67226.c
new file mode 100644
index 00000000000..c533496cbc6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr67226.c
@@ -0,0 +1,42 @@
+struct assembly_operand
+{
+ int type, value, symtype, symflags, marker;
+};
+
+struct assembly_operand to_input, from_input;
+
+void __attribute__ ((__noinline__, __noclone__))
+assemblez_1 (int internal_number, struct assembly_operand o1)
+{
+ if (o1.type != from_input.type)
+ __builtin_abort ();
+}
+
+void __attribute__ ((__noinline__, __noclone__))
+t0 (struct assembly_operand to, struct assembly_operand from)
+{
+ if (to.value == 0)
+ assemblez_1 (32, from);
+ else
+ __builtin_abort ();
+}
+
+int
+main (void)
+{
+ to_input.value = 0;
+ to_input.type = 1;
+ to_input.symtype = 2;
+ to_input.symflags = 3;
+ to_input.marker = 4;
+
+ from_input.value = 5;
+ from_input.type = 6;
+ from_input.symtype = 7;
+ from_input.symflags = 8;
+ from_input.marker = 9;
+
+ t0 (to_input, from_input);
+
+ return 0;
+}