diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-02-23 08:49:06 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-02-23 08:49:06 +0100 |
commit | b607e75e25261ac2c81d71fe1a4dcf5fcd166603 (patch) | |
tree | c83ce2682d44020d9ccc173ce01b86a17929c8a2 /gcc/internal-fn.c | |
parent | 18eb304e5f35d745dcb1a9bb41a2879a364f59fe (diff) | |
download | gcc-b607e75e25261ac2c81d71fe1a4dcf5fcd166603.zip gcc-b607e75e25261ac2c81d71fe1a4dcf5fcd166603.tar.gz gcc-b607e75e25261ac2c81d71fe1a4dcf5fcd166603.tar.bz2 |
re PR middle-end/79665 (gcc's signed (x*x)/200 is slower than clang's)
PR middle-end/79665
* internal-fn.c (get_range_pos_neg): Moved to ...
* tree.c (get_range_pos_neg): ... here. No longer static.
* tree.h (get_range_pos_neg): New prototype.
* expr.c (expand_expr_real_2) <case TRUNC_DIV_EXPR>: If both arguments
are known to be in between 0 and signed maximum inclusive, try to
expand both unsigned and signed divmod and use the cheaper one from
those.
From-SVN: r245676
Diffstat (limited to 'gcc/internal-fn.c')
-rw-r--r-- | gcc/internal-fn.c | 80 |
1 files changed, 0 insertions, 80 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 1d84b26..ffe291d 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -413,86 +413,6 @@ expand_FALLTHROUGH (internal_fn, gcall *call) "invalid use of attribute %<fallthrough%>"); } -/* Helper function for expand_addsub_overflow. Return 1 - if ARG interpreted as signed in its precision is known to be always - positive or 2 if ARG is known to be always negative, or 3 if ARG may - be positive or negative. */ - -static int -get_range_pos_neg (tree arg) -{ - if (arg == error_mark_node) - return 3; - - int prec = TYPE_PRECISION (TREE_TYPE (arg)); - int cnt = 0; - if (TREE_CODE (arg) == INTEGER_CST) - { - wide_int w = wi::sext (arg, prec); - if (wi::neg_p (w)) - return 2; - else - return 1; - } - while (CONVERT_EXPR_P (arg) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0))) - && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec) - { - arg = TREE_OPERAND (arg, 0); - /* Narrower value zero extended into wider type - will always result in positive values. */ - if (TYPE_UNSIGNED (TREE_TYPE (arg)) - && TYPE_PRECISION (TREE_TYPE (arg)) < prec) - return 1; - prec = TYPE_PRECISION (TREE_TYPE (arg)); - if (++cnt > 30) - return 3; - } - - if (TREE_CODE (arg) != SSA_NAME) - return 3; - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) - { - gimple *g = SSA_NAME_DEF_STMT (arg); - if (is_gimple_assign (g) - && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g))) - { - tree t = gimple_assign_rhs1 (g); - if (INTEGRAL_TYPE_P (TREE_TYPE (t)) - && TYPE_PRECISION (TREE_TYPE (t)) <= prec) - { - if (TYPE_UNSIGNED (TREE_TYPE (t)) - && TYPE_PRECISION (TREE_TYPE (t)) < prec) - return 1; - prec = TYPE_PRECISION (TREE_TYPE (t)); - arg = t; - if (++cnt > 30) - return 3; - continue; - } - } - return 3; - } - if (TYPE_UNSIGNED (TREE_TYPE (arg))) - { - /* For unsigned values, the "positive" range comes - below the "negative" range. */ - if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED)) - return 1; - if (wi::neg_p (wi::sext (arg_min, prec), SIGNED)) - return 2; - } - else - { - if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED)) - return 1; - if (wi::neg_p (wi::sext (arg_max, prec), SIGNED)) - return 2; - } - return 3; -} - /* Return minimum precision needed to represent all values of ARG in SIGNed integral type. */ |