https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127605

--- Comment #2 from Drea Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Drea Pinski from comment #1)
> /* Fold (((X >> C1) & C2) << C3) into (X >>/<< |C1 - C3|) & (C2' << C3),
>    where C2' is obtained from C2 by clearing all but the rightmost C1 bits. 
> */
> (simplify
>  (lshift (bit_and (rshift @0 INTEGER_CST@1) INTEGER_CST@2) INTEGER_CST@3)
>   (if (TYPE_UNSIGNED (TREE_TYPE (@0))
>        && type_has_mode_precision_p (TREE_TYPE (@0)))
>    (with { int prec = TYPE_PRECISION (TREE_TYPE (@0)); }
>     (if (wi::ltu_p (wi::to_wide (@1), prec)
>          && wi::ltu_p (wi::to_wide (@3), prec))
>      (with
>       {
>         /* Clear the first PREC - @1 bits of the mask, then shift it.  */
>         wide_int mask_lz = wi::mask (prec - tree_to_uhwi (@1), false, prec);
>         tree mask = fold_build2 (BIT_AND_EXPR, TREE_TYPE (@0),
>                         @2, wide_int_to_tree (TREE_TYPE (@0), mask_lz));
>         tree mask_shifted = fold_build2 (LSHIFT_EXPR, TREE_TYPE (@0),
>                                          mask, @3);
>       }
>       (if (wi::leu_p (wi::to_wide (@1), wi::to_wide (@3))) // <<< Here
>        (bit_and (lshift @0 (minus @3 @1)) { mask_shifted; })
>        (bit_and (rshift @0 (minus @1 @3)) { mask_shifted; })))))))
> 
> Shifts rhs types don't have to match; so need to use to_widest instead.
> r17-4511-g885ad73e630ca2

Or use tree_to_uhwi for that last if.  since you already check if them are less
than a TYPE_PRECISION (16bit field), they will fit in an unsigned HOST_WIDE_INT
already anyways.

Reply via email to