https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125405
--- Comment #4 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Drea Pinski from comment #3)
> (In reply to Milan Tripkovic from comment #1)
> > With the following patterns:
> >
> > (simplify
> > (minus (bit_and @0 INTEGER_CST@1) (bit_and @0 INTEGER_CST@2))
> > (if (INTEGRAL_TYPE_P (type)
> > && TYPE_PRECISION (type) > 8
> > && wi::to_wide (@1) == 127
> > && wi::to_wide (@2) == 128)
> > (convert (convert:signed_char_type_node @0))))
> > (simplify
> > (minus (bit_and @0 INTEGER_CST@1) (bit_and @0 INTEGER_CST@2))
> > (if (INTEGRAL_TYPE_P (type)
> > && TYPE_PRECISION (type) > 16
> > && wi::to_wide (@1) == 32767
> > && wi::to_wide (@2) == 32768)
> > (convert (convert:intHI_type_node @0))))
>
> I wonder if we could do this better and more generic.
> Maybe something like:
> (simplify
> (minus (bit_and @0 INTEGER_CST@1) (bit_and @0 integer_pow2p@2))
> (if (wi::to_wide (@1) + 1 == wi::to_wide (@2))
> (with { tree ntype = build_nonstandard_integer_type (wi::exact_log2
> (wi::to_wide (@2)), SIGNED); }
> (convert (convert:ntype @0)))
`wi::exact_log2 (wi::to_wide (@2))` needs to have `+1` added to it; I think.
That is 32768 is 1<<15 but we want 16 here.
I had an off by one error :).
>
> >
> > GCC is able to canonicalize the mask/sub idioms to sign-extension forms.
> > For RISC-V, this gives the expected shift-based sequences:
> >
> > sext8_hd:
> > slliw a0,a0,24
> > sraiw a0,a0,24
> > ret
> >
> > sext16_hd:
> > slliw a0,a0,16
> > sraiw a0,a0,16
> > ret
> >
> > Would this be considered the right direction for handling this optimization?