This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
IA64 HP-UX patch for gcc.c-torture/compile/20040624-1.c
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 6 Aug 2004 15:21:51 -0700 (PDT)
- Subject: IA64 HP-UX patch for gcc.c-torture/compile/20040624-1.c
- Reply-to: sje at cup dot hp dot com
This is a patch to fix gcc.c-torture/compile/20040624-1.c on HP-UX IA64.
The test has a return type of a structure containing a single floating
point variable (Which makes it an HFA, a homogeneous floating point
aggregate, in IA64 terms) and currently generates an ICE.
| 20040624-1.c:3: internal compiler error: in convert_move, at expr.c:335
| Please submit a full bug report,
| with preprocessed source if appropriate.
| See <URL:http://gcc.gnu.org/bugs.html> for instructions.
The bug is in
ia64_function_value where we have:
if (i == 1)
return XEXP (loc[0], 0);
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
The corresponding code from ia64_function_arg is:
/* If we ended up using just one location, just return that one loc, but
change the mode back to the argument mode. However, we can't do this
when hfa_mode is XFmode and mode is TImode. In that case, we would
return a TImode reference to an FP reg, but FP regs can't hold TImode.
We need the PARALLEL to make this work. This can happen for a union
containing a single __float80 member. */
if (i == 1 && ! (hfa_mode == XFmode && mode == TImode))
return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
Now I could fix the test by copying the ia64_function_arg code into
ia64_function_value but I was wondering about the value of special
casing the single element situation, because I can also fix this by
simply using PARALLEL all the time.
In terms of the code generated, the code generated with PARALLEL
actually seems better because it loads/stores directly into or out of
the floaing point register. With the gen_rtx_REG version we generate
code that uses an integer register as an intermediary.
The only downside I could see to using PARALLEL all the time is in
expand_call, where if the return value is in a PARALLEL we decide that
the call is not "cse'able" but maybe the SSA work / tree optimizations
make that a moot point.
Anyway, here is a patch to use PARALLEL all the time (in
ia64_function_arg and in ia64_function_value) and which was tested with
no regressions. Let me know if this is OK or if I should do it the
other way.
Steve Ellcey
sje@cup.hp.com
2004-07-15 Steve Ellcey <sje@cup.hp.com>
* config/ia64/ia64.c (ia64_function_arg): Use PARALLEL even if there
is only one reg.
(ia64_function_value): Ditto.
*** gcc.orig/gcc/gcc/config/ia64/ia64.c Fri Aug 6 14:56:47 2004
--- gcc/gcc/gcc/config/ia64/ia64.c Fri Aug 6 14:57:29 2004
*************** ia64_function_arg (CUMULATIVE_ARGS *cum,
*** 3682,3698 ****
else if (gr_size > UNITS_PER_WORD)
int_regs += gr_size / UNITS_PER_WORD;
}
!
! /* If we ended up using just one location, just return that one loc, but
! change the mode back to the argument mode. However, we can't do this
! when hfa_mode is XFmode and mode is TImode. In that case, we would
! return a TImode reference to an FP reg, but FP regs can't hold TImode.
! We need the PARALLEL to make this work. This can happen for a union
! containing a single __float80 member. */
! if (i == 1 && ! (hfa_mode == XFmode && mode == TImode))
! return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
! else
! return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
/* Integral and aggregates go in general registers. If we have run out of
--- 3682,3688 ----
else if (gr_size > UNITS_PER_WORD)
int_regs += gr_size / UNITS_PER_WORD;
}
! return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
/* Integral and aggregates go in general registers. If we have run out of
*************** ia64_function_value (tree valtype, tree
*** 3990,4000 ****
GEN_INT (offset));
offset += hfa_size;
}
!
! if (i == 1)
! return XEXP (loc[0], 0);
! else
! return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
return gen_rtx_REG (mode, FR_ARG_FIRST);
--- 3980,3986 ----
GEN_INT (offset));
offset += hfa_size;
}
! return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
return gen_rtx_REG (mode, FR_ARG_FIRST);