On Thu, 10 Dec 2020, Richard Sandiford wrote:

> Richard Biener <rguent...@suse.de> writes:
> >> @@ -812,33 +997,80 @@ split_constant_offset_1 (tree type, tree op0, enum 
> >> tree_code code, tree op1,
> >>      }
> >>  }
> >>  
> >> -/* Expresses EXP as VAR + OFF, where off is a constant.  The type of OFF
> >> -   will be ssizetype.  */
> >> +/* If EXP has pointer type, try to express it as:
> >> +
> >> +     POINTER_PLUS <*VAR, (sizetype) *OFF>
> >> +
> >> +   where:
> >> +
> >> +   - *VAR has the same type as EXP
> >> +   - *OFF is a constant of type ssizetype.
> >> +
> >> +   If EXP has an integral type, try to express (sizetype) EXP as:
> >> +
> >> +     *VAR + (sizetype) *OFF
> >> +
> >> +   where:
> >> +
> >> +   - *VAR has type sizetype
> >> +   - *OFF is a constant of type ssizetype.
> >> +
> >> +   If EXP_RANGE is nonnull, set it to the range of EXP.
> >> +
> >> +   CACHE caches {*VAR, *OFF} pairs for SSA names that we've previously
> >> +   visited.  LIMIT counts down the number of SSA names that we are
> >> +   allowed to process before giving up.  */
> >>  
> >>  static void
> >> -split_constant_offset (tree exp, tree *var, tree *off,
> >> +split_constant_offset (tree exp, tree *var, tree *off, value_range 
> >> *exp_range,
> >>                   hash_map<tree, std::pair<tree, tree> > &cache,
> >>                   unsigned *limit)
> >>  {
> >> -  tree type = TREE_TYPE (exp), op0, op1, e, o;
> >> +  tree type = TREE_TYPE (exp), op0, op1;
> >>    enum tree_code code;
> >>  
> >> -  *var = exp;
> >> -  *off = ssize_int (0);
> >> +  code = TREE_CODE (exp);
> >> +  if (exp_range)
> >> +    {
> >> +      *exp_range = type;
> >> +      if (code == SSA_NAME)
> >> +  {
> >> +    wide_int var_min, var_max;
> >> +    value_range_kind vr_kind = get_range_info (exp, &var_min, &var_max);
> >> +    wide_int var_nonzero = get_nonzero_bits (exp);
> >> +    vr_kind = intersect_range_with_nonzero_bits (vr_kind,
> >> +                                                 &var_min, &var_max,
> >> +                                                 var_nonzero,
> >> +                                                 TYPE_SIGN (type));
> >> +    if (vr_kind == VR_RANGE)
> >> +      *exp_range = value_range (type, var_min, var_max);
> >> +  }
> >> +    }
> >>  
> >> -  if (tree_is_chrec (exp)
> >> -      || get_gimple_rhs_class (TREE_CODE (exp)) == GIMPLE_TERNARY_RHS)
> >> -    return;
> >> +  if (!tree_is_chrec (exp)
> >> +      && get_gimple_rhs_class (TREE_CODE (exp)) != GIMPLE_TERNARY_RHS)
> >> +    {
> >> +      extract_ops_from_tree (exp, &code, &op0, &op1);
> >> +      if (split_constant_offset_1 (type, op0, code, op1, var, off,
> >> +                             exp_range, cache, limit))
> >> +  return;
> >> +    }
> >>  
> >> -  code = TREE_CODE (exp);
> >> -  extract_ops_from_tree (exp, &code, &op0, &op1);
> >> -  if (split_constant_offset_1 (type, op0, code, op1, &e, &o, cache, 
> >> limit))
> >> +  *var = exp;
> >> +  if (INTEGRAL_TYPE_P (type))
> >> +    *var = fold_convert (sizetype, *var);
> >> +  *off = ssize_int (0);
> >> +  if (exp_range && code != SSA_NAME)
> >>      {
> >> -      *var = e;
> >> -      *off = o;
> >> +      wide_int var_min, var_max;
> >> +      if (determine_value_range (exp, &var_min, &var_max) == VR_RANGE)
> >> +  *exp_range = value_range (type, var_min, var_max);
> >
> > So this call is only for the case the recursion failed, otherwise
> > we build exp_range during the recursive call, correct?
> 
> Yeah, that's right.
> 
> > The patch is OK.
> 
> Thanks.  For the record, now also tested on x86_64-linux-gnu.
> 
> I'm not sure what to do about backports though.  It seems a bit
> invasive for GCC 8 and 9 at least (PR95396).

I'd say we try for GCC 10 and only then decide (which means GCC 8
very likely not getting it).

Richard.

Reply via email to