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

--- Comment #14 from rguenther at suse dot de <rguenther at suse dot de> ---
On Fri, 20 May 2016, rdapp at linux dot vnet.ibm.com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69526
> 
> --- Comment #13 from rdapp at linux dot vnet.ibm.com ---
> Created attachment 38535
>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38535&action=edit
> VRP/match.pd patch
> 
> Found some time again and hacked together a fix for match.pd and VRP. The 
> patch
> exports a VRP function no_range_overflow that is called from match.pd via
> tree.c. I realize that VRP didn't export any functions so far and if there's a
> better/idiomatic way to do it, please tell me. Further improvements or "code
> smell" hints very welcome.
> 
> Currently this should fix cases like
> 
> long foo(int i)
> {
>   return (long) (i + 1) - 2;
> }
> 
> Commutativity of a PLUS_EXPR is not yet being exploited and I'm relying on
> TYPE_OVERFLOW_UNDEFINED so far. The overflow checking could also be done more
> elegantly I suppose.
> 
> This diff is extracted from the full patch which also includes the RTL level
> fix which I haven't included here since it has not changed. I hope the
> splitting didn't introduce new bugs but there are no regressions on s390x for
> the full patch.

So I think you should use get_range_info () instead of exporting stuff
from VRP.  Plus change the pattern to be more explicit about the
inner operation (the comment suggests you care about +- only). Thus

(for outer_op (plus minus)
 (for inner_op (plus minus)
  (simplify
   (outer_op (convert (inner_op SSA_NAME@0 INTEGER_CST@1)) INTEGER_CST@2))

VRP only has ranges for types that would combine with INTEGER_CSTs,
not other constants so using INTEGER_CST is better here.  The above
has the advantage that you don't need to lookup SSA def stmts in
your manually written code.  For the range of @0 you'd then do

  (with
    {
      wide_int rmin, rmax;
      enum value_range_type rtype = get_range_info (@0, &rmin, &rmax);

and you'd use wide-int operations to check for overflow rather than
const_binop and looking for TREE_OVERFLOW.  Both wi::add and wi::sub
have variants with a overflow flag.

As you rely on range-info the transform is indeed GIMPLE only but
please follow other cases and wrap the whole pattern in

#if GIMPLE
#endif

so it does not produce dead code in generic-match.c

Reply via email to