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

--- Comment #7 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
GCC already support similar simplication in expr_to_aff_combination

           /* If inner type has undefined overflow behavior, fold conversion
 332               for below two cases:
 333                 (T1)(X *+- CST) -> (T1)X *+- (T1)CST
 334                 (T1)(X + X)     -> (T1)X + (T1)X.  */
 335            if (TYPE_OVERFLOW_UNDEFINED (itype)
 336                && (TREE_CODE (op1) == INTEGER_CST
 337                    || (icode == PLUS_EXPR && operand_equal_p (op0, op1,
0))))
 338              {
 339                op0 = fold_convert (otype, op0);
 340                op1 = fold_convert (otype, op1);
 341                return expr_to_aff_combination (comb, icode, otype, op0,
op1);
 342              }
 343            wide_int minv, maxv;
 344            /* If inner type has wrapping overflow behavior, fold
conversion
 345               for below case:
 346                 (T1)(X *+- CST) -> (T1)X *+- (T1)CST
 347               if X *+- CST doesn't overflow by range information.  */
 348            int_range_max vr;
 349            if (TYPE_UNSIGNED (itype)
 350                && TYPE_OVERFLOW_WRAPS (itype)
 351                && TREE_CODE (op1) == INTEGER_CST
 352                && get_range_query (cfun)->range_of_expr (vr, op0)
 353                && !vr.varying_p ()
 354                && !vr.undefined_p ())
 355              {
 356                wide_int minv = vr.lower_bound ();
 357                wide_int maxv = vr.upper_bound ();
 358                wi::overflow_type overflow = wi::OVF_NONE;
 359                signop sign = UNSIGNED;
 360                if (icode == PLUS_EXPR)
 361                  wi::add (maxv, wi::to_wide (op1), sign, &overflow);
 362                else if (icode == MULT_EXPR)
 363                  wi::mul (maxv, wi::to_wide (op1), sign, &overflow);
 364                else
 365                  wi::sub (minv, wi::to_wide (op1), sign, &overflow);
 366
 367                if (overflow == wi::OVF_NONE)
 368                  {
 369                    op0 = fold_convert (otype, op0);
 370                    op1 = fold_convert (otype, op1);
 371                    return expr_to_aff_combination (comb, icode, otype,
op0,


Directly define a new simplication for (T1) (T2) ((U) X + CST) -> (T1) X + (T1)
CST doesn't work since it relies on contextual stmt info for the overflow
guarantee, but in tree-affine.c only global ranger is available.

One possible solution is supporting contextual ranger in ivopts, and passed it
down to tree-affine, simplify (T1) (T2) ((U) X + CST) when it's known there's
no overflow.

Reply via email to