On Wed, Jun 14, 2017 at 4:55 PM, Will Schmidt <will_schm...@vnet.ibm.com> wrote: > 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. :-)
Yeah, sorry -- the gimple_build machinery handles this GIMPLE wart transparently but gimple_build_assign does not ... Richard. > -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; >> > } > > >