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 <kuganv@linaro.org> 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 <kuganv@linaro.org> * c-common.c (c_common_truthvalue_conversion): Handle ABSU_EXPR. gcc/c/ChangeLog: 2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org> * 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 <kuganv@linaro.org> * constexpr.c (potential_constant_expression_1): Handle ABSU_EXPR. * cp-gimplify.c (cp_fold): Likewise. gcc/testsuite/ChangeLog: 2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org> 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
This commit is contained in:
parent
ee79110cfd
commit
e197e64ee8
|
@ -1,3 +1,24 @@
|
|||
2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
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 <jakub@redhat.com>
|
||||
|
||||
PR middle-end/86095
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
* c-common.c (c_common_truthvalue_conversion): Handle ABSU_EXPR.
|
||||
|
||||
2018-06-13 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* c-opts.c (c_common_post_options): Warn about useless -Wabi.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
* 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 <jakub@redhat.com>
|
||||
|
||||
PR c/86093
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
* constexpr.c (potential_constant_expression_1): Handle ABSU_EXPR.
|
||||
* cp-gimplify.c (cp_fold): Likewise.
|
||||
|
||||
2018-06-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/86147 - wrong capture for template argument.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
11
gcc/match.pd
11
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 <x>
|
||||
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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2018-06-16 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
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 <jakub@redhat.com>
|
||||
|
||||
PR c/86093
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
/* { 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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" } } */
|
|
@ -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 } } */
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue