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