On Mon, Jun 11, 2018 at 10:28 AM Kugan Vivekanandarajah <kugan.vivekanandara...@linaro.org> wrote: > > Hi Richard, > > Thanks for the review and sorry for getting back to you late. > > On 4 June 2018 at 18:38, Richard Biener <richard.guent...@gmail.com> wrote: > > On Mon, Jun 4, 2018 at 10:18 AM Kugan Vivekanandarajah > > <kugan.vivekanandara...@linaro.org> wrote: > >> > >> Hi Richard, > >> > >> Thanks for the review. > >> > >> On 1 June 2018 at 22:20, Richard Biener <richard.guent...@gmail.com> wrote: > >> > On Fri, Jun 1, 2018 at 4:12 AM Kugan Vivekanandarajah > >> > <kugan.vivekanandara...@linaro.org> wrote: > >> >> > >> >> Hi Richard, > >> >> > >> >> This is the revised patch based on the review and the discussion in > >> >> https://gcc.gnu.org/ml/gcc/2018-05/msg00179.html. > >> >> > >> >> In summary: > >> >> - I skipped (element_precision (type) < element_precision (TREE_TYPE > >> >> (@0))) in the match.pd pattern as this would prevent transformation > >> >> for the case in PR. > >> >> that is, I am interested in is something like: > >> >> char t = (char) ABS_EXPR <(int) x> > >> >> and I want to generate > >> >> char t = (char) ABSU_EXPR <x> > >> >> > >> >> - I also haven't added all the necessary match.pd changes for > >> >> ABSU_EXPR. I have a patch for that but will submit separately based on > >> >> this reveiw. > >> >> > >> >> - I also tried to add ABSU_EXPRsupport in the places as necessary by > >> >> grepping for ABS_EXPR. > >> >> > >> >> - I also had to add special casing in vectorizer for ABSU_EXP as its > >> >> result is unsigned type. > >> >> > >> >> Is this OK. Patch bootstraps and the regression test is ongoing. > >> > > >> > The c/c-typeck.c:build_unary_op change looks unnecessary - the > >> > C FE should never generate this directly (the c-common one might > >> > be triggered by early folding I guess). > >> > >> The Gimple FE testcase is running into this. > > > > Ah, OK then. > > > >> > > >> > @@ -1761,6 +1762,9 @@ const_unop (enum tree_code code, tree type, tree > >> > arg0) > >> > if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == > >> > REAL_CST) > >> > return fold_abs_const (arg0, type); > >> > break; > >> > + case ABSU_EXPR: > >> > + return fold_convert (type, fold_abs_const (arg0, > >> > + signed_type_for > >> > (type))); > >> > > >> > case CONJ_EXPR: > >> > > >> > I think this will get you bogus TREE_OVERFLOW flags set on ABSU > >> > (-INT_MIN). > >> > > >> > I think you want to change fold_abs_const to properly deal with arg0 > >> > being > >> > signed and type unsigned. That is, sth like > >> > > >> > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > >> > index 6f80f1b1d69..f60f9c77e91 100644 > >> > --- a/gcc/fold-const.c > >> > +++ b/gcc/fold-const.c > >> > @@ -13843,18 +13843,19 @@ fold_abs_const (tree arg0, tree type) > >> > { > >> > /* If the value is unsigned or non-negative, then the absolute > >> > value > >> > is the same as the ordinary value. */ > >> > - if (!wi::neg_p (wi::to_wide (arg0), TYPE_SIGN (type))) > >> > - t = arg0; > >> > + wide_int val = wi::to_wide (arg0); > >> > + bool overflow = false; > >> > + if (!wi::neg_p (val, TYPE_SIGN (TREE_TYPE (arg0)))) > >> > + ; > >> > > >> > /* If the value is negative, then the absolute value is > >> > its negation. */ > >> > else > >> > - { > >> > - bool overflow; > >> > - wide_int val = wi::neg (wi::to_wide (arg0), &overflow); > >> > - t = force_fit_type (type, val, -1, > >> > - overflow | TREE_OVERFLOW (arg0)); > >> > - } > >> > + wide_int val = wi::neg (val, &overflow); > >> > + > >> > + /* Force to the destination type, set TREE_OVERFLOW for signed > >> > + TYPE only. */ > >> > + t = force_fit_type (type, val, 1, overflow | TREE_OVERFLOW > >> > (arg0)); > >> > } > >> > break; > >> > > >> > and then simply share the const_unop code with ABS_EXPR. > >> > >> Done. > >> > >> > diff --git a/gcc/match.pd b/gcc/match.pd > >> > index 14386da..7d7c132 100644 > >> > --- a/gcc/match.pd > >> > +++ b/gcc/match.pd > >> > @@ -102,6 +102,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > >> > (match (nop_convert @0) > >> > @0) > >> > > >> > +(simplify (abs (convert @0)) > >> > + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > >> > + && !TYPE_UNSIGNED (TREE_TYPE (@0)) > >> > + && !TYPE_UNSIGNED (type)) > >> > + (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } > >> > + (convert (absu:utype @0))))) > >> > + > >> > + > >> > > >> > please put a comment before the pattern. I believe there's no > >> > need to check for !TYPE_UNSIGNED (type). Note this > >> > also converts abs ((char)int-var) to (char)absu(int-var) which > >> > doesn't make sense. The original issue you want to address > >> > here is the case where TYPE_PRECISION of @0 is less than > >> > the precision of type. That is, you want to remove language > >> > introduced integer promotion of @0 which only is possible > >> > with ABSU. So please do add such precision check > >> > (I simply suggested the bogus direction of the test). > >> > >> Done. > >> > > >> > diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c > >> > index 68f4fd3..9b62583 100644 > >> > --- a/gcc/tree-cfg.c > >> > +++ b/gcc/tree-cfg.c > >> > @@ -3685,6 +3685,12 @@ verify_gimple_assign_unary (gassign *stmt) > >> > case PAREN_EXPR: > >> > case CONJ_EXPR: > >> > break; > >> > + case ABSU_EXPR: > >> > + if (!TYPE_UNSIGNED (lhs_type) > >> > + || !ANY_INTEGRAL_TYPE_P (rhs1_type)) > >> > > >> > if (!ANY_INTEGRAL_TYPE_P (lhs_type) > >> > || !TYPE_UNSIGNED (lhs_type) > >> > || !ANY_INTEGRAL_TYPE_P (rhs1_type) > >> > || TYPE_UNSIGNED (rhs1_type) > >> > || element_precision (lhs_type) != element_precision (rhs1_type)) > >> > { > >> > error ("invalid types for ABSU_EXPR"); > >> > debug_generic_expr (lhs_type); > >> > debug_generic_expr (rhs1_type); > >> > return true; > >> > } > >> > > > > > ^^^ you forgot this one. > > > > > >> > + return true; > >> > + return false; > >> > + break; > >> > > >> > diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c > >> > index 30c6d9e..44b1399 100644 > >> > --- a/gcc/tree-eh.c > >> > +++ b/gcc/tree-eh.c > >> > @@ -2465,6 +2465,7 @@ operation_could_trap_helper_p (enum tree_code op, > >> > > >> > case NEGATE_EXPR: > >> > case ABS_EXPR: > >> > + case ABSU_EXPR: > >> > case CONJ_EXPR: > >> > /* These operations don't trap with floating point. */ > >> > if (honor_trapv) > >> > > >> > ABSU never traps. Please instead unconditionally return false. > >> Done. > >> > >> > > >> > diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c > >> > index 66c78de..b52d714 100644 > >> > --- a/gcc/tree-vect-stmts.c > >> > +++ b/gcc/tree-vect-stmts.c > >> > @@ -5995,7 +5995,11 @@ vectorizable_operation (gimple *stmt, > >> > gimple_stmt_iterator *gsi, > >> > "transform binary/unary operation.\n"); > >> > > >> > /* Handle def. */ > >> > - vec_dest = vect_create_destination_var (scalar_dest, vectype); > >> > + if (code == ABSU_EXPR) > >> > + vec_dest = vect_create_destination_var (scalar_dest, > >> > + unsigned_type_for (vectype)); > >> > + else > >> > + vec_dest = vect_create_destination_var (scalar_dest, vectype); > >> > > >> > /* POINTER_DIFF_EXPR has pointer arguments which are vectorized as > >> > vectors with unsigned elements, but the result is signed. So, we > >> > > >> > simply use vectype_out for creation of vec_dest. > >> Done. > > > > /* Handle def. */ > > - vec_dest = vect_create_destination_var (scalar_dest, vectype); > > + if (code == ABSU_EXPR) > > + vec_dest = vect_create_destination_var (scalar_dest, vectype_out); > > + else > > + vec_dest = vect_create_destination_var (scalar_dest, vectype); > > > > I meant _always_ vectype_out. Thus unconditionally > > > > vec_dest = vect_create_destination_var (scalar_dest, vectype_out); > > Some testcases are failing with the changes. > > gcc:gcc.dg/tree-ssa/pr83329.c (internal compiler error) : This seems > to be due to POINTER_DIFF_EXPR (?)
Ah, yes. I'd simply handle that in a more clear way. > There is also > > gcc:gcc.target/i386/avx2-vshift-1.c (internal compiler error) > gcc:gcc.target/i386/xop-vshift-1.c (internal compiler error) > > Example: > /home/tcwg-buildslave/workspace/tcwg-buildfarm_2/tcwg-x86_32-build/snapshots/gcc.git~master_rev_bfa6b77/gcc/testsuite/gcc.target/i386/xop-vshift-1.c:73:1: > error: type mismatch in binary expression^M > vector(4) long long unsigned int^M > ^M > vector(4) long long int^M > ^M > vector(4) long long int^M > ^M > vect_patt_17.54_21 = vect__2.53_16 & vect_cst__20;^M > during GIMPLE pass: vect^M That one is odd and looks like a latent bug in pattern creation: diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 507c5b94f07..6786ffcd4c6 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -2185,6 +2185,11 @@ vect_recog_vector_vector_shift_pattern (vec<gimple *> *stmts, TYPE_PRECISION (TREE_TYPE (oprnd1))); def = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL); def_stmt = gimple_build_assign (def, BIT_AND_EXPR, rhs1, mask); + stmt_vec_info new_stmt_info + = new_stmt_vec_info (def_stmt, vinfo); + set_vinfo_for_stmt (def_stmt, new_stmt_info); + STMT_VINFO_VECTYPE (new_stmt_info) + = get_vectype_for_scalar_type (TREE_TYPE (rhs1)); new_pattern_def_seq (stmt_vinfo, def_stmt); } } I can see if I can make this change independently of yours (that is, I'm bootstrapping and testing the above together with an equivalent vectorizable_operation hunk). Richard. > > Thanks, > Kugan > > > > > > > OK with those two changes. > > > > Thanks, > > Richard. > > > >> > > >> > diff --git a/gcc/tree.def b/gcc/tree.def > >> > index c660b2c..5fec781 100644 > >> > --- a/gcc/tree.def > >> > +++ b/gcc/tree.def > >> > @@ -760,6 +760,7 @@ DEFTREECODE (MAX_EXPR, "max_expr", tcc_binary, 2) > >> > An ABS_EXPR must have either an INTEGER_TYPE or a REAL_TYPE. The > >> > operand of the ABS_EXPR must have the same type. */ > >> > DEFTREECODE (ABS_EXPR, "abs_expr", tcc_unary, 1) > >> > +DEFTREECODE (ABSU_EXPR, "absu_expr", tcc_unary, 1) > >> > > >> > /* Shift operations for shift and rotate. > >> > Shift means logical shift if done on an > >> > > >> > You can clearly see that the comment before ABS_EXPR doesn't apply to > >> > ABSU_EXPR > >> > so please add an appropriate one. I suggest > >> > > >> > /* Represents the unsigned absolute value of the operand. > >> > An ABSU_EXPR must have unsigned INTEGER_TYPE. The operand of the > >> > ABSU_EXPR > >> > must have the corresponding signed type. */ > >> > >> Done. > >> > >> Here is the reviesed patch. Is this OK? > >> > >> Thanks, > >> Kugan > >> > >> > > >> > Otherwise looks OK. (I didn't explicitely check for missing ABSU_EXPR > >> > handling this time) > >> > > >> > Thanks, > >> > Richard. > >> > > >> > > >> >> Thanks, > >> >> Kugan > >> >> > >> >> > >> >> On 18 May 2018 at 12:36, Kugan Vivekanandarajah > >> >> <kugan.vivekanandara...@linaro.org> wrote: > >> >> > Hi Richard, > >> >> > > >> >> > Thanks for the review. I am revising the patch based on Andrew's > >> >> > comments too. > >> >> > > >> >> > On 17 May 2018 at 20:36, Richard Biener <richard.guent...@gmail.com> > >> >> > wrote: > >> >> >> On Thu, May 17, 2018 at 4:56 AM Andrew Pinski <pins...@gmail.com> > >> >> >> wrote: > >> >> >> > >> >> >>> On Wed, May 16, 2018 at 7:14 PM, Kugan Vivekanandarajah > >> >> >>> <kugan.vivekanandara...@linaro.org> wrote: > >> >> >>> > As mentioned in the PR, I am trying to add ABSU_EXPR to fix this > >> >> >>> > issue. In the attached patch, in fold_cond_expr_with_comparison I > >> >> >>> > am > >> >> >>> > generating ABSU_EXPR for these cases. As I understand, absu_expr > >> >> >>> > is > >> >> >>> > well defined in RTL. So, the issue is generating absu_expr and > >> >> >>> > transferring to RTL in the correct way. I am not sure I am not > >> >> >>> > doing > >> >> >>> > all that is needed. I will clean up and add more test-cases based > >> >> >>> > on > >> >> >>> > the feedback. > >> >> >> > >> >> >> > >> >> >>> diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c > >> >> >>> index 71e172c..2b812e5 100644 > >> >> >>> --- a/gcc/optabs-tree.c > >> >> >>> +++ b/gcc/optabs-tree.c > >> >> >>> @@ -235,6 +235,7 @@ optab_for_tree_code (enum tree_code code, > >> >> >>> const_tree > >> >> >> type, > >> >> >>> return trapv ? negv_optab : neg_optab; > >> >> >> > >> >> >>> case ABS_EXPR: > >> >> >>> + case ABSU_EXPR: > >> >> >>> return trapv ? absv_optab : abs_optab; > >> >> >> > >> >> >> > >> >> >>> This part is not correct, it should something like this: > >> >> >> > >> >> >>> case ABS_EXPR: > >> >> >>> return trapv ? absv_optab : abs_optab; > >> >> >>> + case ABSU_EXPR: > >> >> >>> + return abs_optab ; > >> >> >> > >> >> >>> Because ABSU is not undefined at the TYPE_MAX. > >> >> >> > >> >> >> Also > >> >> >> > >> >> >> /* Unsigned abs is simply the operand. Testing here means > >> >> >> we don't > >> >> >> risk generating incorrect code below. */ > >> >> >> - if (TYPE_UNSIGNED (type)) > >> >> >> + if (TYPE_UNSIGNED (type) > >> >> >> + && (code != ABSU_EXPR)) > >> >> >> return op0; > >> >> >> > >> >> >> is wrong. ABSU of an unsigned number is still just that number. > >> >> >> > >> >> >> The change to fold_cond_expr_with_comparison looks odd to me > >> >> >> (premature optimization). It should be done separately - it seems > >> >> >> you are doing > >> >> > > >> >> > FE seems to be using this to generate ABS_EXPR from > >> >> > c_fully_fold_internal to fold_build3_loc and so on. I changed this to > >> >> > generate ABSU_EXPR for the case in the testcase. So the question > >> >> > should be, in what cases do we need ABS_EXPR and in what cases do we > >> >> > need ABSU_EXPR. It is not very clear to me. > >> >> > > >> >> > > >> >> >> > >> >> >> (simplify (abs (convert @0)) (convert (absu @0))) > >> >> >> > >> >> >> here. > >> >> >> > >> >> >> You touch one other place in fold-const.c but there seem to be many > >> >> >> more that need ABSU_EXPR handling (you touched the one needed > >> >> >> for correctness) - esp. you should at least handle constant folding > >> >> >> in const_unop and the nonnegative predicate. > >> >> > > >> >> > OK. > >> >> >> > >> >> >> @@ -3167,6 +3167,9 @@ verify_expr (tree *tp, int *walk_subtrees, > >> >> >> void *data > >> >> >> ATTRIBUTE_UNUSED) > >> >> >> CHECK_OP (0, "invalid operand to unary operator"); > >> >> >> break; > >> >> >> > >> >> >> + case ABSU_EXPR: > >> >> >> + break; > >> >> >> + > >> >> >> case REALPART_EXPR: > >> >> >> case IMAGPART_EXPR: > >> >> >> > >> >> >> verify_expr is no more. Did you test this recently against trunk? > >> >> > > >> >> > This patch is against slightly older trunk. I will rebase it. > >> >> > > >> >> >> > >> >> >> @@ -3937,6 +3940,9 @@ verify_gimple_assign_unary (gassign *stmt) > >> >> >> case PAREN_EXPR: > >> >> >> case CONJ_EXPR: > >> >> >> break; > >> >> >> + case ABSU_EXPR: > >> >> >> + /* FIXME. */ > >> >> >> + return false; > >> >> >> > >> >> >> no - please not! Please add verification here - ABSU should be only > >> >> >> called on INTEGRAL, vector or complex INTEGRAL types and the > >> >> >> type of the LHS should be always the unsigned variant of the > >> >> >> argument type. > >> >> > > >> >> > OK. > >> >> >> > >> >> >> if (is_gimple_val (cond_expr)) > >> >> >> return cond_expr; > >> >> >> > >> >> >> - if (TREE_CODE (cond_expr) == ABS_EXPR) > >> >> >> + if (TREE_CODE (cond_expr) == ABS_EXPR > >> >> >> + || TREE_CODE (cond_expr) == ABSU_EXPR) > >> >> >> { > >> >> >> rhs1 = TREE_OPERAND (cond_expr, 1); > >> >> >> STRIP_USELESS_TYPE_CONVERSION (rhs1); > >> >> >> > >> >> >> err, but the next line just builds a ABS_EXPR ... > >> >> >> > >> >> >> How did you identify spots that need adjustment? I would expect that > >> >> >> once folding generates ABSU_EXPR that you need to adjust frontends > >> >> >> (C++ constexpr handling for example). Also I miss adjustments > >> >> >> to gimple-pretty-print.c and the GIMPLE FE parser. > >> >> > > >> >> > I will add this. > >> >> >> > >> >> >> recursively grepping throughout the whole gcc/ tree doesn't reveal > >> >> >> too many > >> >> >> cases of ABS_EXPR so I think it's reasonable to audit all of them. > >> >> >> > >> >> >> I also miss some trivial absu simplifications in match.pd. There > >> >> >> are not > >> >> >> a lot of abs cases but similar ones would be good to have initially. > >> >> > > >> >> > I will add them in the next version. > >> >> > > >> >> > Thanks, > >> >> > Kugan > >> >> > > >> >> >> > >> >> >> Thanks for tackling this! > >> >> >> Richard. > >> >> >> > >> >> >>> Thanks, > >> >> >>> Andrew > >> >> >> > >> >> >>> > > >> >> >>> > Thanks, > >> >> >>> > Kugan > >> >> >>> > > >> >> >>> > > >> >> >>> > gcc/ChangeLog: > >> >> >>> > > >> >> >>> > 2018-05-13 Kugan Vivekanandarajah > >> >> >>> > <kugan.vivekanandara...@linaro.org> > >> >> >>> > > >> >> >>> > * expr.c (expand_expr_real_2): Handle ABSU_EXPR. > >> >> >>> > * fold-const.c (fold_cond_expr_with_comparison): Generate > >> >> >>> > ABSU_EXPR > >> >> >>> > (fold_unary_loc): Handle ABSU_EXPR. > >> >> >>> > * optabs-tree.c (optab_for_tree_code): Likewise. > >> >> >>> > * tree-cfg.c (verify_expr): Likewise. > >> >> >>> > (verify_gimple_assign_unary): Likewise. > >> >> >>> > * tree-if-conv.c (fold_build_cond_expr): Likewise. > >> >> >>> > * tree-inline.c (estimate_operator_cost): Likewise. > >> >> >>> > * tree-pretty-print.c (dump_generic_node): Likewise. > >> >> >>> > * tree.def (ABSU_EXPR): New. > >> >> >>> > > >> >> >>> > gcc/testsuite/ChangeLog: > >> >> >>> > > >> >> >>> > 2018-05-13 Kugan Vivekanandarajah > >> >> >>> > <kugan.vivekanandara...@linaro.org> > >> >> >>> > > >> >> >>> > * gcc.dg/absu.c: New test.