On Fri, Sep 10, 2021 at 2:58 PM liuhongt <hongtao....@intel.com> wrote: > > gcc/ChangeLog: > > * expmed.c (extract_bit_field_using_extv): validate_subreg > before call gen_lowpart. > --- > gcc/expmed.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/gcc/expmed.c b/gcc/expmed.c > index 3143f38e057..10d62d857a8 100644 > --- a/gcc/expmed.c > +++ b/gcc/expmed.c > @@ -1571,12 +1571,16 @@ extract_bit_field_using_extv (const extraction_insn > *extv, rtx op0, > > if (GET_MODE (target) != ext_mode) > { > + machine_mode tmode = GET_MODE (target); > /* Don't use LHS paradoxical subreg if explicit truncation is needed > between the mode of the extraction (word_mode) and the target > mode. Instead, create a temporary and use convert_move to set > the target. */ > if (REG_P (target) > - && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode))
^^^ I wonder if herein lies the problem in that the HFmode "truncation" from SImode is considered noop? Note the underlying target hook only looks at the mode precision and thus receives 16 and 32, and thus maybe that TRULY_NOOP_TRUNCATION_MODES_P query only makes sense for integer modes? Though the documentation of the hook only talks about "conversion" of "values" ... So maybe a targetm.modes_tieable_p (GET_MODE (target), extmode) check is missing? > + && TRULY_NOOP_TRUNCATION_MODES_P (tmode, ext_mode) > + && validate_subreg (ext_mode, tmode, > + target, > + subreg_lowpart_offset (ext_mode, tmode))) > { > target = gen_lowpart (ext_mode, target); > if (partial_subreg_p (GET_MODE (spec_target), ext_mode)) > -- > 2.27.0 >