https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125405
--- Comment #3 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(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)))
>
> 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?