On Tue, 2017-06-13 at 10:03 +0200, Richard Biener wrote: > On Mon, Jun 12, 2017 at 11:56 PM, Will Schmidt > <will_schm...@vnet.ibm.com> wrote: > > Hi, > > > > > > diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c > > index 63ca2d1..55592fb 100644 > > --- a/gcc/config/rs6000/rs6000.c > > +++ b/gcc/config/rs6000/rs6000.c > > @@ -16588,6 +16588,83 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator > > *gsi) > > gsi_replace (gsi, g, true); > > return true; > > } <snip> > > + /* Flavors of vector shift right. */ > > + case ALTIVEC_BUILTIN_VSRB: > > + case ALTIVEC_BUILTIN_VSRH: > > + case ALTIVEC_BUILTIN_VSRW: > > + case P8V_BUILTIN_VSRD: > > + { > > + arg0 = gimple_call_arg (stmt, 0); > > + arg1 = gimple_call_arg (stmt, 1); > > + lhs = gimple_call_lhs (stmt); > > + gimple *g; > > + /* convert arg0 to unsigned. */ > > + arg0 = convert (unsigned_type_for (TREE_TYPE (arg0)), arg0); > > Please do not use 'convert', instead do ...
Hi Richard, V3 of this patch , using the gimple_build() convenience helper function has been posted, and is the direction I'm going for with this patch. I wanted to make sure I fully understood the other options though, so I have a question/clarification on the other suggestions: > > + tree arg0_uns = create_tmp_reg_or_ssa_name > > + (unsigned_type_for (TREE_TYPE (arg0))); > > + g = gimple_build_assign (arg0_uns, arg0); > > g = gimple_build_assign (arg0_uns, VIEW_CONVERT_EXPR, usigned_type, arg0); I tried a few trivial variations of this: g = gimple_build_assign (arg0_uns, VIEW_CONVERT_EXPR, unsigned_type_for (TREE_TYPE(arg0_uns)), arg0); which lookd good, but it asserts in gimple_build_assign_1(), on the check "if (op2) { gcc_assert (num_ops > 2); ... Trolling around the other code for references, i found and tried this, which uses the build1() helper, and appears to work. Is this the gist of what you suggested, or would there be another alternative? g = gimple_build_assign (arg0_uns, build1(VIEW_CONVERT_EXPR, unsigned_type_for (TREE_TYPE(arg0_uns)), arg0)); Thanks for the feedback, etc. :-) -Will > You also want to avoid spitting out useless copies here if the > arg/result is already unsigned, > like via > > tree arg0_uns = arg0; > if (! TYPE_UNSIGNED (TREE_TYPE (arg0_uns))) > { > ... > } > > > + gimple_set_location (g, gimple_location (stmt)); > > + gsi_insert_before (gsi, g, GSI_SAME_STMT); > > + /* convert lhs to unsigned and do the shift. */ > > Just use lhs if it has the same sign as arg0_uns. > > > + tree lhs_uns = create_tmp_reg_or_ssa_name > > + (unsigned_type_for (TREE_TYPE (lhs))); > > You can re-use the type of arg0_uns here. > > > + g = gimple_build_assign (lhs_uns, RSHIFT_EXPR, arg0_uns, arg1); > > + gimple_set_location (g, gimple_location (stmt)); > > + gsi_insert_before (gsi, g, GSI_SAME_STMT); > > + /* convert lhs back to a signed type for the return. */ > > + lhs_uns = convert (signed_type_for (TREE_TYPE (lhs)),lhs_uns); > > + g = gimple_build_assign (lhs, lhs_uns); > > See above for how to perform the conversion. > > Note that you could use the gimple_build convenience to shorten the code > sequence above to > > gimple_seq stmts = NULL; > tree arg0_unsigned = gimple_build (&stmts, VIEW_CONVERT_EXPR, > > unsigned_type_for (...), arg0); > tree res = gimple_build (&stmts, RSHIFT_EXPR, TREE_TYPE (arg0_uns), > arg0_uns, arg1); > res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res); > gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); > update_call_from_tree (gsi, res); > > The above gimple_build sequence will fold all the stmts thus remove > useless conversions and apply constant folding, etc. > > Richard. > > > + gimple_set_location (g, gimple_location (stmt)); > > + gsi_replace (gsi, g, true); > > + return true; > > + } > > default: > > break; > > }