Richard Biener <rguent...@suse.de> writes:
> This removes the odd check of size_type_node when handling left-shifts
> as multiplications of 1 << N and instead uses the type as specified.
> It also moves left-shift handling next to multiplications where it
> semantically belongs.
>
> Boostrap and regtest pending on x86_64-unknown-linux-gnu.
>
> OK?  (I failed to short-cut the wide_int_to_tree for a
> poly_int_cst_p bottom)
>
> Thanks,
> Richard.
>
> 2022-01-24  Richard Biener  <rguent...@suse.de>
>
>       * fold-const.cc (multiple_of_p): Re-write and move LSHIFT_EXPR
>       handling.
> ---
>  gcc/fold-const.cc | 33 ++++++++++++++++-----------------
>  1 file changed, 16 insertions(+), 17 deletions(-)
>
> diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
> index b155611578d..a0a4913c45e 100644
> --- a/gcc/fold-const.cc
> +++ b/gcc/fold-const.cc
> @@ -14068,7 +14068,7 @@ int
>  multiple_of_p (tree type, const_tree top, const_tree bottom)
>  {
>    gimple *stmt;
> -  tree t1, op1, op2;
> +  tree op1, op2;
>  
>    if (operand_equal_p (top, bottom, 0))
>      return 1;
> @@ -14114,6 +14114,21 @@ multiple_of_p (tree type, const_tree top, const_tree 
> bottom)
>        return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom)
>             || multiple_of_p (type, TREE_OPERAND (top, 0), bottom));
>  
> +    case LSHIFT_EXPR:
> +      /* Handle X << CST as X * (1 << CST) and only process the constant.  */
> +      if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
> +     {
> +       op1 = TREE_OPERAND (top, 1);
> +       if (wi::gtu_p (TYPE_PRECISION (type), wi::to_wide (op1)))
> +         {
> +           wide_int mul_op
> +             = wi::one (TYPE_PRECISION (type)) << wi::to_wide (op1);
> +           return multiple_of_p (type,
> +                                 wide_int_to_tree (type, mul_op), bottom);
> +         }
> +     }
> +      return 0;
> +

LGTM.  Sorry for the slow response.

I guess the condition could be written:

    if (wi::to_widest (op1) < TYPE_PRECISION (type))

which might be more readable, and also avoids accidentally reinterpreting
a sign.

Thanks,
Richard

>      case MINUS_EXPR:
>        /* It is impossible to prove if op0 - op1 is multiple of bottom
>        precisely, so be conservative here checking if both op0 and op1
> @@ -14133,22 +14148,6 @@ multiple_of_p (tree type, const_tree top, const_tree 
> bottom)
>        return (multiple_of_p (type, op1, bottom)
>             && multiple_of_p (type, TREE_OPERAND (top, 0), bottom));
>  
> -    case LSHIFT_EXPR:
> -      if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
> -     {
> -       op1 = TREE_OPERAND (top, 1);
> -       /* const_binop may not detect overflow correctly,
> -          so check for it explicitly here.  */
> -       if (wi::gtu_p (TYPE_PRECISION (TREE_TYPE (size_one_node)),
> -                      wi::to_wide (op1))
> -           && (t1 = fold_convert (type,
> -                                  const_binop (LSHIFT_EXPR, size_one_node,
> -                                               op1))) != 0
> -           && !TREE_OVERFLOW (t1))
> -         return multiple_of_p (type, t1, bottom);
> -     }
> -      return 0;
> -
>      CASE_CONVERT:
>        /* Can't handle conversions from non-integral or wider integral type.  
> */
>        if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)

Reply via email to