From: Kugan Vivekanandarajah Date: Sat, 16 Jun 2018 21:34:29 +0000 (+0000) Subject: re PR tree-optimization/64946 ([AArch64] gcc.target/aarch64/vect-abs-compile.c -... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e197e64ee8ab8e46de9069a8d951bed720a0fd67;p=gcc.git re PR tree-optimization/64946 ([AArch64] gcc.target/aarch64/vect-abs-compile.c - "abs" vectorization fails for char/short types) gcc/ChangeLog: 2018-06-16 Kugan Vivekanandarajah PR middle-end/64946 * cfgexpand.c (expand_debug_expr): Hande ABSU_EXPR. * config/i386/i386.c (ix86_add_stmt_cost): Likewise. * dojump.c (do_jump): Likewise. * expr.c (expand_expr_real_2): Check operand type's sign. * fold-const.c (const_unop): Handle ABSU_EXPR. (fold_abs_const): Likewise. * gimple-pretty-print.c (dump_unary_rhs): Likewise. * gimple-ssa-backprop.c (backprop::process_assign_use): Likesie. (strip_sign_op_1): Likesise. * match.pd: Add new pattern to generate ABSU_EXPR. * optabs-tree.c (optab_for_tree_code): Handle ABSU_EXPR. * tree-cfg.c (verify_gimple_assign_unary): Likewise. * tree-eh.c (operation_could_trap_helper_p): Likewise. * tree-inline.c (estimate_operator_cost): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-vect-patterns.c (vect_recog_sad_pattern): Likewise. * tree.def (ABSU_EXPR): New. gcc/c-family/ChangeLog: 2018-06-16 Kugan Vivekanandarajah * c-common.c (c_common_truthvalue_conversion): Handle ABSU_EXPR. gcc/c/ChangeLog: 2018-06-16 Kugan Vivekanandarajah * c-typeck.c (build_unary_op): Handle ABSU_EXPR; * gimple-parser.c (c_parser_gimple_statement): Likewise. (c_parser_gimple_unary_expression): Likewise. gcc/cp/ChangeLog: 2018-06-16 Kugan Vivekanandarajah * constexpr.c (potential_constant_expression_1): Handle ABSU_EXPR. * cp-gimplify.c (cp_fold): Likewise. gcc/testsuite/ChangeLog: 2018-06-16 Kugan Vivekanandarajah PR middle-end/64946 * gcc.dg/absu.c: New test. * gcc.dg/gimplefe-29.c: New test. * gcc.target/aarch64/pr64946.c: New test. From-SVN: r261681 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c320b876176..fe24ad300db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2018-06-16 Kugan Vivekanandarajah + + PR middle-end/64946 + * cfgexpand.c (expand_debug_expr): Hande ABSU_EXPR. + * config/i386/i386.c (ix86_add_stmt_cost): Likewise. + * dojump.c (do_jump): Likewise. + * expr.c (expand_expr_real_2): Check operand type's sign. + * fold-const.c (const_unop): Handle ABSU_EXPR. + (fold_abs_const): Likewise. + * gimple-pretty-print.c (dump_unary_rhs): Likewise. + * gimple-ssa-backprop.c (backprop::process_assign_use): Likesie. + (strip_sign_op_1): Likesise. + * match.pd: Add new pattern to generate ABSU_EXPR. + * optabs-tree.c (optab_for_tree_code): Handle ABSU_EXPR. + * tree-cfg.c (verify_gimple_assign_unary): Likewise. + * tree-eh.c (operation_could_trap_helper_p): Likewise. + * tree-inline.c (estimate_operator_cost): Likewise. + * tree-pretty-print.c (dump_generic_node): Likewise. + * tree-vect-patterns.c (vect_recog_sad_pattern): Likewise. + * tree.def (ABSU_EXPR): New. + 2018-06-16 Jakub Jelinek PR middle-end/86095 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index a1c20973ecf..d4e5942e49d 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2018-06-16 Kugan Vivekanandarajah + + * c-common.c (c_common_truthvalue_conversion): Handle ABSU_EXPR. + 2018-06-13 Jason Merrill * c-opts.c (c_common_post_options): Warn about useless -Wabi. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 859eeb47252..0e8efb53f40 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/ChangeLog b/gcc/c/ChangeLog index 89e6d1373b4..f1ff69e8fdd 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-06-16 Kugan Vivekanandarajah + + * c-typeck.c (build_unary_op): Handle ABSU_EXPR; + * gimple-parser.c (c_parser_gimple_statement): Likewise. + (c_parser_gimple_unary_expression): Likewise. + 2018-06-15 Jakub Jelinek PR c/86093 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 5e2a2836d6d..aa70b23ff10 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -4319,6 +4319,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 8f1c4425c09..1be5d14dc2d 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 9bd61b9948e..9b91279282e 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4545,6 +4545,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 95cfa05ce61..f88680703ed 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -50350,6 +50350,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/ChangeLog b/gcc/cp/ChangeLog index 2e341f10527..0879dd72753 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2018-06-16 Kugan Vivekanandarajah + + * constexpr.c (potential_constant_expression_1): Handle ABSU_EXPR. + * cp-gimplify.c (cp_fold): Likewise. + 2018-06-15 Jason Merrill PR c++/86147 - wrong capture for template argument. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 93de6162c04..4670076a6fa 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5816,6 +5816,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 b4e23e26b86..4567365b48b 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 9da8a0e3091..88cc96ae85a 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 793b283842a..56751df8431 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8962,6 +8962,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) @@ -8973,7 +8974,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 c85a9912435..4568e1e2b57 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1726,7 +1726,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,7 @@ const_unop (enum tree_code code, tree type, tree arg0) } case ABS_EXPR: + case ABSU_EXPR: if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST) return fold_abs_const (arg0, type); break; @@ -13867,20 +13869,21 @@ 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)); - } + 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; + break; case REAL_CST: if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0))) diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 405d9e3e3bc..bee81ad7271 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 bbc6311ff28..d554826216f 100644 --- a/gcc/gimple-ssa-backprop.c +++ b/gcc/gimple-ssa-backprop.c @@ -413,6 +413,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; @@ -688,6 +689,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 7e22771ec7c..c1e0963da9a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -102,6 +102,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (match (nop_convert @0) @0) +/* Transform likes of (char) ABS_EXPR <(int) x> into (char) ABSU_EXPR + ABSU_EXPR returns unsigned absolute value of the operand and the operand + of the ABSU_EXPR will have the corresponding signed type. */ +(simplify (abs (convert @0)) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && element_precision (type) > element_precision (TREE_TYPE (@0))) + (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 11cea175caa..1c7181a5748 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -251,6 +251,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/ChangeLog b/gcc/testsuite/ChangeLog index 03fc2a0f309..af7d3d8bb1b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-06-16 Kugan Vivekanandarajah + + PR middle-end/64946 + * gcc.dg/absu.c: New test. + * gcc.dg/gimplefe-29.c: New test. + * gcc.target/aarch64/pr64946.c: New test. + 2018-06-15 Jakub Jelinek PR c/86093 diff --git a/gcc/testsuite/gcc.dg/absu.c b/gcc/testsuite/gcc.dg/absu.c new file mode 100644 index 00000000000..e2428cdbc19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/absu.c @@ -0,0 +1,45 @@ + +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +#include +#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); + +int 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); + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/gimplefe-29.c b/gcc/testsuite/gcc.dg/gimplefe-29.c new file mode 100644 index 00000000000..54b86ef86fb --- /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/testsuite/gcc.target/aarch64/pr64946.c b/gcc/testsuite/gcc.target/aarch64/pr64946.c new file mode 100644 index 00000000000..736656fcc96 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr64946.c @@ -0,0 +1,13 @@ + +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +signed char a[100],b[100]; +void absolute_s8 (void) +{ + int i; + for (i=0; i<16; i++) + a[i] = (b[i] > 0 ? b[i] : -b[i]); +}; + +/* { dg-final { scan-assembler-times "abs\tv\[0-9\]+.16b, v\[0-9\]+.16b" 1 } } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 85e845ff097..a22fed5d1c9 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3722,6 +3722,20 @@ verify_gimple_assign_unary (gassign *stmt) case CONJ_EXPR: break; + case ABSU_EXPR: + 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; + } + return false; + case VEC_DUPLICATE_EXPR: if (TREE_CODE (lhs_type) != VECTOR_TYPE || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type)) diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 06fe748f339..f367040af45 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2471,6 +2471,10 @@ operation_could_trap_helper_p (enum tree_code op, return true; return false; + case ABSU_EXPR: + /* ABSU_EXPR never traps. */ + return false; + case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR: diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index ca4dc321d20..161cdd4facc 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3801,6 +3801,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 63276bce5be..63ec823c0ba 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2462,6 +2462,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 74f08cf8528..6621392b7e8 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -615,7 +615,8 @@ vect_recog_sad_pattern (vec *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.def b/gcc/tree.def index cee41c2a9c9..49bc423c0a8 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -752,6 +752,11 @@ DEFTREECODE (MAX_EXPR, "max_expr", tcc_binary, 2) operand of the ABS_EXPR must have the same type. */ DEFTREECODE (ABS_EXPR, "abs_expr", tcc_unary, 1) +/* 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. */ +DEFTREECODE (ABSU_EXPR, "absu_expr", tcc_unary, 1) + /* Shift operations for shift and rotate. Shift means logical shift if done on an unsigned type, arithmetic shift if done on a signed type.