Richard Sandiford <[email protected]> writes:
> The problem seems to be that mode-switching overloads VXRM_MODE_NONE
> to mean both "no requirement" and "unknown state". So we have:
>
> static int
> singleton_vxrm_need (void)
> {
> /* Only needed for vector code. */
> if (!TARGET_VECTOR)
> return VXRM_MODE_NONE;
This was a bad example, sorry. What matters more is that non-vector
instructions are also VXRM_MODE_NONE. Or more specifically:
>
> and:
>
> if (vxrm_unknown_p (insn))
> return VXRM_MODE_NONE;
>
> This means that VXRM is assumed to be transparent in an instruction
> that matches vxrm_unknown_p.
...the function:
static int
riscv_vxrm_mode_after (rtx_insn *insn, int mode)
{
if (vxrm_unknown_p (insn))
return VXRM_MODE_NONE;
if (recog_memoized (insn) < 0)
return mode;
if (reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM), PATTERN (insn)))
return get_attr_vxrm_mode (insn);
else
return mode;
}
will return VXRM_MODE_NONE if:
(a) insn is something like a call
(b) insn is a normal instruction that does not mention VXRM at all and
mode is already VXRM_MODE_NONE
(b) is the transparent case but (a) is a kill. Since the block walk
starts with VXRM_MODE_NONE as the initial mode, there needs to be
another mode that (a) can use to indicate a kill.
Thanks,
Richard