Thanks, Feng ________________________________________ From: Feng Xue OS <f...@os.amperecomputing.com> Sent: Wednesday, August 19, 2020 5:17 PM To: Richard Biener Cc: gcc-patches@gcc.gnu.org; Marc Glisse Subject: [PATCH V2] Add pattern for pointer-diff on addresses with same base/offset (PR 94234)
As Richard's comment, this patch is composed to simplify generalized binary-with-convert pattern like ((T) X) OP ((T) Y). Instead of creating almost duplicated rules into match.pd, we try to transform it to (T) (X OP Y), and apply simplification on (X OP Y) in forwprop pass. Regards, Feng --- 2020-08-19 Feng Xue <f...@os.amperecomputing.com> gcc/ PR tree-optimization/94234 * tree-ssa-forwprop.c (simplify_binary_with_convert): New function. * (fwprop_ssa_val): Move it before its new caller. gcc/testsuite/ PR tree-optimization/94234 * gcc.dg/ifcvt-3.c: Modified to suppress forward propagation. * gcc.dg/tree-ssa/20030807-10.c: Likewise. * gcc.dg/pr94234-2.c: New test. > ________________________________________ > From: Richard Biener <richard.guent...@gmail.com> > Sent: Monday, June 15, 2020 3:41 PM > To: Feng Xue OS > Cc: gcc-patches@gcc.gnu.org; Marc Glisse > Subject: Re: [PATCH] Add pattern for pointer-diff on addresses with same > base/offset (PR 94234) > > On Fri, Jun 5, 2020 at 11:20 AM Feng Xue OS <f...@os.amperecomputing.com> > wrote: >> >> As Marc suggested, removed the new pointer_diff rule, and add another rule >> to fold >> convert-add expression. This new rule is: >> >> (T)(A * C) +- (T)(B * C) -> (T) ((A +- B) * C) >> >> Regards, >> Feng >> >> --- >> 2020-06-01 Feng Xue <f...@os.amperecomputing.com> >> >> gcc/ >> PR tree-optimization/94234 >> * match.pd ((T)(A * C) +- (T)(B * C)) -> (T)((A +- B) * C): New >> simplification. >> * ((PTR_A + OFF) - (PTR_B + OFF)) -> (PTR_A - PTR_B): New >> simplification. >> >> gcc/testsuite/ >> PR tree-optimization/94234 >> * gcc.dg/pr94234.c: New test. >> --- >> gcc/match.pd | 28 ++++++++++++++++++++++++++++ >> gcc/testsuite/gcc.dg/pr94234.c | 24 ++++++++++++++++++++++++ >> 2 files changed, 52 insertions(+) >> create mode 100644 gcc/testsuite/gcc.dg/pr94234.c >> >> diff --git a/gcc/match.pd b/gcc/match.pd >> index 33ee1a920bf..4f340bfe40a 100644 >> --- a/gcc/match.pd >> +++ b/gcc/match.pd >> @@ -2515,6 +2515,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) >> && TREE_CODE (@2) == INTEGER_CST >> && tree_int_cst_sign_bit (@2) == 0)) >> (minus (convert @1) (convert @2))))) >> + (simplify >> + (pointer_diff (pointer_plus @0 @2) (pointer_plus @1 @2)) >> + (pointer_diff @0 @1)) > > This new pattern is OK. Please commit it separately. > >> (simplify >> (pointer_diff (pointer_plus @@0 @1) (pointer_plus @0 @2)) >> /* The second argument of pointer_plus must be interpreted as signed, >> and >> @@ -2526,6 +2529,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) >> (minus (convert (view_convert:stype @1)) >> (convert (view_convert:stype @2))))))) >> >> +/* (T)(A * C) +- (T)(B * C) -> (T)((A +- B) * C) and >> + (T)(A * C) +- (T)(A) -> (T)(A * (C +- 1)). */ >> +(if (INTEGRAL_TYPE_P (type)) >> + (for plusminus (plus minus) >> + (simplify >> + (plusminus (convert:s (mult:cs @0 @1)) (convert:s (mult:cs @0 @2))) >> + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) >> + && (TYPE_OVERFLOW_UNDEFINED (type) || TYPE_OVERFLOW_WRAPS (type)) >> + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) >> + (convert (mult (plusminus @1 @2) @0)))) >> + (simplify >> + (plusminus (convert @0) (convert@2 (mult:c@3 @0 @1))) >> + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) >> + && (TYPE_OVERFLOW_UNDEFINED (type) || TYPE_OVERFLOW_WRAPS (type)) >> + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) >> + && single_use (@2) && single_use (@3)) >> + (convert (mult (plusminus { build_one_cst (TREE_TYPE (@1)); } @1) >> @0)))) >> + (simplify >> + (plusminus (convert@2 (mult:c@3 @0 @1)) (convert @0)) >> + (if (element_precision (type) <= element_precision (TREE_TYPE (@0)) >> + && (TYPE_OVERFLOW_UNDEFINED (type) || TYPE_OVERFLOW_WRAPS (type)) >> + && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) >> + && single_use (@2) && single_use (@3)) >> + (convert (mult (plusminus @1 { build_one_cst (TREE_TYPE (@1)); }) >> @0)))))) >> + > > This shows the limit of pattern matching IMHO. I'm also not convinced > it gets the > overflow cases correct (but I didn't spend too much time here). Note we have > similar functionality implemented in fold_plusminus_mult_expr. IMHO instead > of doing the above moving fold_plusminus_mult_expr to GIMPLE by executing > it from inside the forwprop pass would make more sense. Or finally biting the > bullet and try to teach reassociation about how to handle signed arithmetic > with non-wrapping overflow behavior. > > Richard.