74 lines
2.0 KiB
Diff
74 lines
2.0 KiB
Diff
2007-06-14 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR middle-end/32285
|
|
* calls.c (precompute_arguments): Also precompute CALL_EXPR arguments
|
|
if ACCUMULATE_OUTGOING_ARGS.
|
|
|
|
* gcc.c-torture/execute/20070614-1.c: New test.
|
|
|
|
--- gcc/calls.c.jj 2007-06-13 17:38:55.000000000 +0200
|
|
+++ gcc/calls.c 2007-06-14 14:50:56.000000000 +0200
|
|
@@ -1269,13 +1269,25 @@ precompute_arguments (int flags, int num
|
|
|
|
/* If this is a libcall, then precompute all arguments so that we do not
|
|
get extraneous instructions emitted as part of the libcall sequence. */
|
|
- if ((flags & ECF_LIBCALL_BLOCK) == 0)
|
|
+
|
|
+ /* If we preallocated the stack space, and some arguments must be passed
|
|
+ on the stack, then we must precompute any parameter which contains a
|
|
+ function call which will store arguments on the stack.
|
|
+ Otherwise, evaluating the parameter may clobber previous parameters
|
|
+ which have already been stored into the stack. (we have code to avoid
|
|
+ such case by saving the outgoing stack arguments, but it results in
|
|
+ worse code) */
|
|
+ if ((flags & ECF_LIBCALL_BLOCK) == 0 && !ACCUMULATE_OUTGOING_ARGS)
|
|
return;
|
|
|
|
for (i = 0; i < num_actuals; i++)
|
|
{
|
|
enum machine_mode mode;
|
|
|
|
+ if ((flags & ECF_LIBCALL_BLOCK) == 0
|
|
+ && TREE_CODE (args[i].tree_value) != CALL_EXPR)
|
|
+ continue;
|
|
+
|
|
/* If this is an addressable type, we cannot pre-evaluate it. */
|
|
gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)));
|
|
|
|
--- gcc/testsuite/gcc.c-torture/execute/20070614-1.c.jj 2007-06-14 15:32:28.000000000 +0200
|
|
+++ gcc/testsuite/gcc.c-torture/execute/20070614-1.c 2007-06-11 13:23:19.000000000 +0200
|
|
@@ -0,0 +1,33 @@
|
|
+extern void abort (void);
|
|
+
|
|
+_Complex v = 3.0 + 1.0iF;
|
|
+
|
|
+void
|
|
+foo (_Complex z, int *x)
|
|
+{
|
|
+ if (z != v)
|
|
+ abort ();
|
|
+}
|
|
+
|
|
+_Complex bar (_Complex z) __attribute__ ((pure));
|
|
+_Complex
|
|
+bar (_Complex z)
|
|
+{
|
|
+ return v;
|
|
+}
|
|
+
|
|
+int
|
|
+baz (void)
|
|
+{
|
|
+ int a, i;
|
|
+ for (i = 0; i < 6; i++)
|
|
+ foo (bar (1.0iF * i), &a);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+main ()
|
|
+{
|
|
+ baz ();
|
|
+ return 0;
|
|
+}
|