On Tue, Feb 22, 2022 at 5:01 AM Zhao Wei Liew via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Tue, 22 Feb 2022 at 11:57, Zhao Wei Liew <zhaoweil...@gmail.com> wrote: > > > > Hi, > > > > This is a partial optimization for PR103855. > > > > Initially, I looked into optimizing RTL generation or a more complex > > GIMPLE transformation so that we could optimize other cases as well, > > such as ((unsigned long long) short / int). > > > > However, that is a bit too complex for now. While I continue to look > > into that change, I've decided to implement this simpler match.pd > > transformation. > > > > Greatly appreciate any feedback on this patch or guidance for > > implementing the more advanced optimizations! > > > > Thanks, > > Zhao Wei > > Sorry, the original patch wasn't recognized as a text file. I've added > a .txt extension to make it explicit.
A few comments - note the change is only appropriate for next stage1. Since we're currently in a regression fixing period reviews can be slow - do not hesitate to ping forgotten patches when stage1 opens again. +/* (type)X / (type)Y -> (type)(X / Y) + when the resulting type is at least precise as the original types + and when all the types are unsigned integral types. */ +(simplify + (trunc_div (convert @0) (convert @1)) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && INTEGRAL_TYPE_P (TREE_TYPE (@1)) + && TYPE_UNSIGNED (type) + && TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_UNSIGNED (TREE_TYPE (@1)) + && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1)) + && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (@0))) + (convert (trunc_div @0 @1)))) since you are requiring the types of @0 and @1 to match it's easier to write && types_match (TREE_TYPE(@0), TREE_TYPE (@1)) that allows you to elide checks on either @0 or @1. I suppose the transform does not work for signed types because of the -INT_MIN / -1 overflow case? It might be possible to use expr_not_equal_to (@0, -INT_MIN) || expr_not_equal_to (@1, -1) (correctly written, lookup the existing examples in match.pd for the X % -Y transform) I'll note that as written the transform will not catch CST / (T)x or (T)x / CST since you'll not see conversions around constants. I'm not sure whether using (convert[12]? ...) or writing special patterns with INTEGER_CST operands is more convenient. There is int_fits_type_p to check whether a constant will fit in a type without truncation or sign change. When @0 and @1 do not have the same type there might still be a common type that can be used and is smaller than 'type', it might be as simple as using build_nonstandard_integer_type (MIN (@0-prec, @1-prec), 1 /*unsigned_p*/). In the past there have been attempts to more globally narrow operations using a new pass rather than using individual patterns. So for more complicated cases that might be the way to go. There's now also the ISEL pass which does pre-RTL expansion transforms that need some global context and for example can look at SSA uses. Richard.