This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix emit_library_call_value to not use virtual stack regs after expand
- From: Maxim Kuvyrkov <maxim at codesourcery dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 24 Jun 2009 16:11:42 +0400
- Subject: [PATCH] Fix emit_library_call_value to not use virtual stack regs after expand
Hello,
The following simple patch [which is just a duplication of a hunk from
within emit_library_call_value_1] fixes ICE when compiling for
m68k/ColdFire machines without hardware divide.
The ICE occurs in reload on gcc.c-torture/execute/loop-3b.c test due to
occurrence of virtual_outgoing_args_rtx in the instruction stream. This
virtual register is used within expand and then is substituted with
(stack_pointer_rtx + STACK_POINTER_OFFSET) at the end of expand.
Evidently, there still remains a way to generate virtual_outgoing_args
by the loop optimizer. The loop optimizer emits a divide instruction
which, due to target not having hwdiv, expands into a library call.
emit_library_call_value_1 deals with virtual_outgoing_args_rtx in two
places: the first already handles case when virtuals are instantiated;
this patch fixes the second.
Tested by bootstrapping on x86_64. OK for trunk?
Thanks,
--
Maxim K.
CodeSourcery
2009-06-24 Maxim Kuvyrkov <maxim@codesourcery.com>
* calls.c (emit_library_call_value_1): Don't use
virtual_outgoing_args register after expand.
Index: gcc/calls.c
===================================================================
--- gcc/calls.c (revision 148831)
+++ gcc/calls.c (working copy)
@@ -3726,8 +3726,25 @@ emit_library_call_value_1 (int retval, r
auto-increment causes confusion. So we merely indicate
that we access something with a known mode somewhere on
the stack. */
- use = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
- gen_rtx_SCRATCH (Pmode));
+ {
+ rtx stack_args;
+
+ /* We must be careful to use virtual regs before
+ they're instantiated, and real regs afterwards.
+ Loop optimization, for example, can create
+ new libcalls after we've instantiated the virtual regs,
+ and if we use virtuals anyway, they won't match
+ the rtl patterns. */
+ if (virtuals_instantiated)
+ stack_args = plus_constant (stack_pointer_rtx,
+ STACK_POINTER_OFFSET);
+ else
+ stack_args = virtual_outgoing_args_rtx;
+
+ use = gen_rtx_PLUS (Pmode, stack_args,
+ gen_rtx_SCRATCH (Pmode));
+ }
+
use = gen_rtx_MEM (argvec[argnum].mode, use);
use = gen_rtx_USE (VOIDmode, use);
call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage);