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)