Message ID | 502E79BC.3080108@arm.com |
---|---|
State | New |
Headers | show |
On 17/08/12 18:05, Richard Earnshaw wrote: > Take two. > > This version should address your concerns about handling > > (u32)u16 * (u32)u16 -> u64 > > We now look at each operand directly, but when doing so we check whether > the operand is the same size as the result or not. When it is, we can > strip any conversion; when it isn't the conversion must preserve > signedness of the inner operand and mustn't be a narrowing conversion. So, if I understand correctly, this simply prevents it from stripping any conversions from the multiply's right-hand-side if they are not widening conversions? That seems fine to me. Not that I have authority to approve it, of course. Andrew
On Fri, Aug 17, 2012 at 7:05 PM, Richard Earnshaw <rearnsha@arm.com> wrote: > On 17/08/12 16:20, Richard Earnshaw wrote: >> Ok, in which case we have to give is_widening_mult_rhs_p enough smarts >> to not strip >> >> (s32)u32 >> >> and return u32. >> >> I'll have another think about it. > > Take two. > > This version should address your concerns about handling > > (u32)u16 * (u32)u16 -> u64 > > We now look at each operand directly, but when doing so we check whether > the operand is the same size as the result or not. When it is, we can > strip any conversion; when it isn't the conversion must preserve > signedness of the inner operand and mustn't be a narrowing conversion. > > * tree-ssa-math-opts.c (widening_mult_conversion_strippable_p): > New function. > (is_widening_mult_rhs_p): Use it. > > Testing underway (again) > > OK? Ok. Thanks, Richard. > R. >
Hi Richard, your patch fails here; I get the build failure: /projects/tob/gcc-git/gcc/gcc/tree-ssa-math-opts.c: In function ‘bool is_widening_mult_rhs_p(tree, tree, tree_node**, tree_node**)’: /projects/tob/gcc-git/gcc/gcc/tree-ssa-math-opts.c:2014:18: error: variable ‘rhs_code’ set but not used [-Werror=unused-but-set-variable] enum tree_code rhs_code; ^ Tobias On 08/17/2012 07:05 PM, Richard Earnshaw wrote: > --- tree-ssa-math-opts.c (revision 190502) > +++ tree-ssa-math-opts.c (local) > @@ -1982,9 +2019,7 @@ is_widening_mult_rhs_p (tree type, tree > if (is_gimple_assign (stmt)) > { > rhs_code = gimple_assign_rhs_code (stmt); > - if (TREE_CODE (type) == INTEGER_TYPE > - ? !CONVERT_EXPR_CODE_P (rhs_code) > - : rhs_code != FIXED_CONVERT_EXPR) > + if (! widening_mult_conversion_strippable_p (type, stmt)) > rhs1 = rhs; > else > { >
--- tree-ssa-math-opts.c (revision 190502) +++ tree-ssa-math-opts.c (local) @@ -1958,6 +1958,43 @@ struct gimple_opt_pass pass_optimize_bsw } }; +/* Return true if stmt is a type conversion operation that can be stripped + when used in a widening multiply operation. */ +static bool +widening_mult_conversion_strippable_p (tree result_type, gimple stmt) +{ + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); + + if (TREE_CODE (result_type) == INTEGER_TYPE) + { + tree op_type; + tree inner_op_type; + + if (!CONVERT_EXPR_CODE_P (rhs_code)) + return false; + + op_type = TREE_TYPE (gimple_assign_lhs (stmt)); + + /* If the type of OP has the same precision as the result, then + we can strip this conversion. The multiply operation will be + selected to create the correct extension as a by-product. */ + if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type)) + return true; + + /* We can also strip a conversion if it preserves the signed-ness of + the operation and doesn't narrow the range. */ + inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt)); + + if (TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type) + && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type)) + return true; + + return false; + } + + return rhs_code == FIXED_CONVERT_EXPR; +} + /* Return true if RHS is a suitable operand for a widening multiplication, assuming a target type of TYPE. There are two cases: @@ -1982,9 +2019,7 @@ is_widening_mult_rhs_p (tree type, tree if (is_gimple_assign (stmt)) { rhs_code = gimple_assign_rhs_code (stmt); - if (TREE_CODE (type) == INTEGER_TYPE - ? !CONVERT_EXPR_CODE_P (rhs_code) - : rhs_code != FIXED_CONVERT_EXPR) + if (! widening_mult_conversion_strippable_p (type, stmt)) rhs1 = rhs; else {