This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
IA64: roblem with OUTGOING_ARG
- From: Michael Matz <matz at suse dot de>
- To: Jim Wilson <wilson at specifixinc dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 14 Nov 2003 19:38:57 +0100 (CET)
- Subject: IA64: roblem with OUTGOING_ARG
Hi Jim,
I have a problem on ia64 with a patch I wrote, which can be tracked down
to some issue in alias analysis. It happens on the 3.3-hammer branch, but
the code in question is still the same in HEAD. The symptom looks like
this:
In ia64_reorg when trying to schedule insns, GCC calculates the
dependencies. The particular case is if the read of
(mem/s/j:QI (reg:DI 2 r2 [367]))
conflicts with some pending writes. In true_dependence() it tries to find
the base term for the above expression, which goes like (from cselib):
(mem/s/j:QI (value:DI) [0 <variable>.desc.bDescriptorType+0 S1 A8])
then get_addr() gives:
(plus:DI (value:DI)
(const_int 1 [0x1]))
the value here stands for (reg:DI 112 r32) which is correct (as r2 is
really r32+1 at that point). But then find_base_term() on the r32
rtx gives
(symbol_ref/f:DI ("*.LC1"))
The problem is as follows: r32 (regno 112) is used for passing arguments
(it here holds a pointer), but later in the function it's also used to
hold the content of 'LC1'. The problem is that the aliasing machinery
only 'sees' the one set of r32, hence it's reg_base_value[112] is the
above symbol-ref. But as it's used also as an argument register the above
symref in fact is _not_ any base value for r32.
I found init_alias_once() which is supposed to fill
static_reg_base_value[] for register used to pass arguments, but for
regno 112 it doesn't do this, because this code:
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
&& HARD_REGNO_MODE_OK (i, Pmode))
static_reg_base_value[i]
= gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
for i==112 doesn't run. FUNCTION_ARG_REGNO_P() gives true for regno==112,
but above it's called with OUTGOING_REGNO(i), which AFAICS for i==112
gives OUT_REG(112 - IN_REG(0)) == OUT_REG (0) == 120.
FUNCTION_ARG_REGNO_P is defined as (shortened):
((REGNO) >= GR_ARG_FIRST && (REGNO) < (GR_ARG_FIRST + MAX_ARGUMENT_SLOTS))
and GR_ARG_FIRST == IN_REG(0) == 112, so FUNCTION_ARG_REGNO_P() gives
false for the above 120.
The comment indicates that F_A_R_P expects outgoing reg numbers, but this
doesn't seem to be the case on ia64. So, what is wrong: the ia64
definitions or the use in init_alias_once ? Or is it the fact that this
is run with really the final register numbers (after all it's
machine_depended_reorg)?
Ciao,
Michael.