Hi! On Mon, Feb 08, 2021 at 12:38:01PM +0000, Richard Sandiford wrote: > Peter Bergner <berg...@linux.ibm.com> writes: > > Adding Richard since he's reviewed the generic opaque mode code in > > the past and this patch contains some more eneric support. > > > > GCC handles pseudos that are used uninitialized, by emitting a > > (set (reg: <reg>) CONST0_RTX(regmode)) before their uninitialized > > pseudo usage. Currently, CONST0_RTX(mode) is NULL for opaque modes, > > which leads to an ICE. The solution is to enhance init_emit_once() to > > add initialization of CONST0_RTX for opaque modes using a target hook, > > since CONST0_RTX probably are different for each opaque mode and each > > target. The default hook throws an error to force the target to think > > hard about what their CONST0_RTX values should be for each mode. > > Hmm, but it looks like the hook uses const0_rtx, i.e. a const_int, > for something that isn't an integer mode. Also, the unspec for XOmode > isn't a constant in the normal sense (CONSTANT_P). > > I think we should either add a new rtx code for constant opaque modes > or make init-regs just emit the clobber for opaque modes (and not emit > the move).
Thanks for looking Richard. That last option sounds good to me as well. Some comments on the patch: > > --- a/gcc/config/rs6000/mma.md > > +++ b/gcc/config/rs6000/mma.md > > @@ -473,9 +473,7 @@ Please look at the commentary in $GCCSRC/.gitattributes on how to get context shown in .md diffs (it needs a local configuration step). > > @@ -16624,6 +16628,19 @@ rs6000_split_multireg_move (rtx dst, rtx src) > > + /* Split the clearing of an OOmode register pair into clearing > > + of its two constituent registers. */ > > + if (REG_P (dst) && mode == OOmode && src == CONST0_RTX (mode)) > > + { > > + int regno = REGNO (dst); > > + gcc_assert (VSX_REGNO_P (regno)); > > + emit_insn (gen_rtx_SET (gen_rtx_REG (reg_mode, regno), > > + CONST0_RTX (reg_mode))); > > + emit_insn (gen_rtx_SET (gen_rtx_REG (reg_mode, regno + 1), > > + CONST0_RTX (reg_mode))); > > + return; > > + } That is fine. > > +/* Implement TARGET_OPAQUE_CONST0_RTX. */ > > + > > +rtx > > +rs6000_opaque_const0_rtx (machine_mode mode) > > +{ > > + gcc_assert (OPAQUE_MODE_P (mode)); > > + > > + switch (mode) > > + { > > + case E_OOmode: > > + return const0_rtx; > > + case E_XOmode: > > + return gen_rtx_UNSPEC (XOmode, gen_rtvec (1, const0_rtx), > > + UNSPEC_MMA_XXSETACCZ); > > + default: > > + gcc_unreachable (); > > + } > > +} Why are XO and OO handled in different ways? This needs a comment, or better, not be handled in different ways ;-) > > --- a/gcc/emit-rtl.c > > +++ b/gcc/emit-rtl.c > > @@ -6408,6 +6408,11 @@ init_emit_once (void) > > if (GET_MODE_CLASS ((machine_mode) i) == MODE_CC) > > const_tiny_rtx[0][i] = const0_rtx; > > > > + FOR_EACH_MODE_IN_CLASS (mode, MODE_OPAQUE) > > + { > > + const_tiny_rtx[0][(int) mode] = targetm.opaque_const0_rtx (mode); > > + } This does not sound like a good idea, it is asking for trouble imo. > > +rtx > > +hook_rtx_mode_unreachable (machine_mode mode ATTRIBUTE_UNUSED) > > +{ > > + gcc_unreachable (); > > +} If you want to use this in any hook, that hook needs documentation that it can not be used on some targets (an ICE is not acceptable from a UI point of view, in almost all cases). > > +DEFHOOK > > +(opaque_const0_rtx, > > + "Return an RTX representing the value @code{0} for opaque mode > > @var{mode}.\n\ > > +The default version of this hook always throws an error.", So that documentation needs a severe warning in it. > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/powerpc/pr98872.c > > @@ -0,0 +1,20 @@ > > +/* PR target/98872 */ > > +/* { dg-do compile } */ > > +/* { dg-require-effective-target power10_ok } */ > > +/* { dg-options "-O2 -mdejagnu-cpu=power10" } */ > > + > > +/* Verify we do not ICE on the tests below. */ Do the existing tests already check the expected code for this? I would expect the code that initialises uninitialised values to handle this, instead (possibly call the same hook, but :-) ) Segher