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. 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.
From 6675f0fe71b1de2c2def5c5d2bd150ae1e707b5c Mon Sep 17 00:00:00 2001 From: Kugan Vivekanandarajah <kugan.vivekanandara...@linaro.org> Date: Tue, 29 May 2018 10:26:23 +1000 Subject: [PATCH] absu v2 Change-Id: Id34948b4d585fbcdcb8ff6eb3728fd3cc6c41bfa --- gcc/c-family/c-common.c | 1 + gcc/c/c-typeck.c | 10 ++++++++++ gcc/c/gimple-parser.c | 9 ++++++++- gcc/cfgexpand.c | 1 + gcc/config/i386/i386.c | 1 + gcc/cp/constexpr.c | 1 + gcc/cp/cp-gimplify.c | 1 + gcc/dojump.c | 1 + gcc/expr.c | 3 ++- gcc/fold-const.c | 6 +++++- gcc/gimple-pretty-print.c | 7 +++++-- gcc/gimple-ssa-backprop.c | 2 ++ gcc/match.pd | 8 ++++++++ gcc/optabs-tree.c | 2 ++ gcc/testsuite/gcc.dg/absu.c | 41 ++++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/gimplefe-29.c | 11 ++++++++++ gcc/tree-cfg.c | 6 ++++++ gcc/tree-eh.c | 1 + gcc/tree-inline.c | 1 + gcc/tree-pretty-print.c | 6 ++++++ gcc/tree-vect-patterns.c | 3 ++- gcc/tree-vect-stmts.c | 6 +++++- gcc/tree.def | 1 + 23 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/absu.c create mode 100644 gcc/testsuite/gcc.dg/gimplefe-29.c diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 859eeb4..0e8efb5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -3312,6 +3312,7 @@ c_common_truthvalue_conversion (location_t location, tree expr) case NEGATE_EXPR: case ABS_EXPR: + case ABSU_EXPR: case FLOAT_EXPR: case EXCESS_PRECISION_EXPR: /* These don't change whether an object is nonzero or zero. */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 45a4529..5bb6804 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -4314,6 +4314,16 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, arg = default_conversion (arg); break; + case ABSU_EXPR: + if (!(typecode == INTEGER_TYPE)) + { + error_at (location, "wrong type argument to absu"); + return error_mark_node; + } + else if (!noconvert) + arg = default_conversion (arg); + break; + case CONJ_EXPR: /* Conjugating a real value is a no-op, but allow it anyway. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index 8f1c442..1be5d14 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -328,7 +328,8 @@ c_parser_gimple_statement (c_parser *parser, gimple_seq *seq) case CPP_NAME: { tree id = c_parser_peek_token (parser)->value; - if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0) + if (strcmp (IDENTIFIER_POINTER (id), "__ABS") == 0 + || strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0) goto build_unary_expr; break; } @@ -638,6 +639,12 @@ c_parser_gimple_unary_expression (c_parser *parser) op = c_parser_gimple_postfix_expression (parser); return parser_build_unary_op (op_loc, ABS_EXPR, op); } + else if (strcmp (IDENTIFIER_POINTER (id), "__ABSU") == 0) + { + c_parser_consume_token (parser); + op = c_parser_gimple_postfix_expression (parser); + return parser_build_unary_op (op_loc, ABSU_EXPR, op); + } else return c_parser_gimple_postfix_expression (parser); } diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 5c323be..d06224d 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4620,6 +4620,7 @@ expand_debug_expr (tree exp) } case ABS_EXPR: + case ABSU_EXPR: return simplify_gen_unary (ABS, mode, op0, mode); case NEGATE_EXPR: diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 637c105..f5a4856 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -51232,6 +51232,7 @@ ix86_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, case BIT_IOR_EXPR: case ABS_EXPR: + case ABSU_EXPR: case MIN_EXPR: case MAX_EXPR: case BIT_XOR_EXPR: diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index a099408..30ea091 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5759,6 +5759,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case FLOAT_EXPR: case NEGATE_EXPR: case ABS_EXPR: + case ABSU_EXPR: case TRUTH_NOT_EXPR: case FIXED_CONVERT_EXPR: case UNARY_PLUS_EXPR: diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index b4e23e2..4567365 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2272,6 +2272,7 @@ cp_fold (tree x) case FLOAT_EXPR: case NEGATE_EXPR: case ABS_EXPR: + case ABSU_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: case FIXED_CONVERT_EXPR: diff --git a/gcc/dojump.c b/gcc/dojump.c index 9da8a0e..88cc96a 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -467,6 +467,7 @@ do_jump (tree exp, rtx_code_label *if_false_label, /* FALLTHRU */ case NON_LVALUE_EXPR: case ABS_EXPR: + case ABSU_EXPR: case NEGATE_EXPR: case LROTATE_EXPR: case RROTATE_EXPR: diff --git a/gcc/expr.c b/gcc/expr.c index ecc5292..a92c23f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9013,6 +9013,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, return REDUCE_BIT_FIELD (temp); case ABS_EXPR: + case ABSU_EXPR: op0 = expand_expr (treeop0, subtarget, VOIDmode, EXPAND_NORMAL); if (modifier == EXPAND_STACK_PARM) @@ -9024,7 +9025,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, /* Unsigned abs is simply the operand. Testing here means we don't risk generating incorrect code below. */ - if (TYPE_UNSIGNED (type)) + if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) return op0; return expand_abs (mode, op0, target, unsignedp, diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0f57f07..20b4271 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1723,7 +1723,8 @@ const_unop (enum tree_code code, tree type, tree arg0) && HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0)) && code != NEGATE_EXPR - && code != ABS_EXPR) + && code != ABS_EXPR + && code != ABSU_EXPR) return NULL_TREE; switch (code) @@ -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: if (TREE_CODE (arg0) == COMPLEX_CST) diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 49e9e12..bb4d259 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -358,14 +358,17 @@ dump_unary_rhs (pretty_printer *buffer, gassign *gs, int spc, break; case ABS_EXPR: + case ABSU_EXPR: if (flags & TDF_GIMPLE) { - pp_string (buffer, "__ABS "); + pp_string (buffer, + rhs_code == ABS_EXPR ? "__ABS " : "__ABSU "); dump_generic_node (buffer, rhs, spc, flags, false); } else { - pp_string (buffer, "ABS_EXPR <"); + pp_string (buffer, + rhs_code == ABS_EXPR ? "ABS_EXPR <" : "ABSU_EXPR <"); dump_generic_node (buffer, rhs, spc, flags, false); pp_greater (buffer); } diff --git a/gcc/gimple-ssa-backprop.c b/gcc/gimple-ssa-backprop.c index 9ab655c..bb378a9 100644 --- a/gcc/gimple-ssa-backprop.c +++ b/gcc/gimple-ssa-backprop.c @@ -408,6 +408,7 @@ backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info) switch (gimple_assign_rhs_code (assign)) { case ABS_EXPR: + case ABSU_EXPR: /* The sign of the input doesn't matter. */ info->flags.ignore_sign = true; break; @@ -675,6 +676,7 @@ strip_sign_op_1 (tree rhs) switch (gimple_assign_rhs_code (assign)) { case ABS_EXPR: + case ABSU_EXPR: case NEGATE_EXPR: return gimple_assign_rhs1 (assign); 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))))) + + /* Simplifications of operations with one constant operand and simplifications to constants or single values. */ diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index 73e6654..092663b 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -234,6 +234,8 @@ optab_for_tree_code (enum tree_code code, const_tree type, case ABS_EXPR: return trapv ? absv_optab : abs_optab; + case ABSU_EXPR: + return abs_optab; default: return unknown_optab; } diff --git a/gcc/testsuite/gcc.dg/absu.c b/gcc/testsuite/gcc.dg/absu.c new file mode 100644 index 0000000..81e37a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/absu.c @@ -0,0 +1,41 @@ + +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +#include <limits.h> +#define ABS(x) (((x) >= 0) ? (x) : -(x)) + +#define DEF_TEST(TYPE) \ +void foo_##TYPE (signed TYPE x, unsigned TYPE y){ \ + TYPE t = ABS (x); \ + if (t != y) \ + __builtin_abort (); \ +} \ + +DEF_TEST (char); +DEF_TEST (short); +DEF_TEST (int); +DEF_TEST (long); +void main () +{ + foo_char (SCHAR_MIN + 1, SCHAR_MAX); + foo_char (0, 0); + foo_char (-1, 1); + foo_char (1, 1); + foo_char (SCHAR_MAX, SCHAR_MAX); + + foo_int (-1, 1); + foo_int (0, 0); + foo_int (INT_MAX, INT_MAX); + foo_int (INT_MIN + 1, INT_MAX); + + foo_short (-1, 1); + foo_short (0, 0); + foo_short (SHRT_MAX, SHRT_MAX); + foo_short (SHRT_MIN + 1, SHRT_MAX); + + foo_long (-1, 1); + foo_long (0, 0); + foo_long (LONG_MAX, LONG_MAX); + foo_long (LONG_MIN + 1, LONG_MAX); +} diff --git a/gcc/testsuite/gcc.dg/gimplefe-29.c b/gcc/testsuite/gcc.dg/gimplefe-29.c new file mode 100644 index 0000000..54b86ef --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-29.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fgimple -fdump-tree-ssa-gimple" } */ + +unsigned int __GIMPLE() f(int a) +{ + unsigned int t0; + t0_1 = __ABSU a; + return t0_1; +} + +/* { dg-final { scan-tree-dump "__ABSU a" "ssa" } } */ 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)) + return true; + return false; + break; case VEC_DUPLICATE_EXPR: if (TREE_CODE (lhs_type) != VECTOR_TYPE 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) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 7881131..665e53c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3865,6 +3865,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights, case MIN_EXPR: case MAX_EXPR: case ABS_EXPR: + case ABSU_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 5a8c8eb..a950a9e 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2463,6 +2463,12 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, pp_greater (pp); break; + case ABSU_EXPR: + pp_string (pp, "ABSU_EXPR <"); + dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); + pp_greater (pp); + break; + case RANGE_EXPR: NIY; break; diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 6da784c..af6b9bd 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -615,7 +615,8 @@ vect_recog_sad_pattern (vec<gimple *> *stmts, tree *type_in, gcc_assert (abs_stmt_vinfo); if (STMT_VINFO_DEF_TYPE (abs_stmt_vinfo) != vect_internal_def) return NULL; - if (gimple_assign_rhs_code (abs_stmt) != ABS_EXPR) + if (gimple_assign_rhs_code (abs_stmt) != ABS_EXPR + && gimple_assign_rhs_code (abs_stmt) != ABSU_EXPR) return NULL; tree abs_oprnd = gimple_assign_rhs1 (abs_stmt); 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 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 -- 2.7.4