aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-12-01 00:27:23 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2018-12-01 00:27:23 +0100
commit4df6a9063433b4f47a2f49535b448408a9dd6b94 (patch)
tree192c96fb9b81b88f5c5727e9b4e6f1b331f4986c /gcc
parente26584b265dc2af4e95d23c4bdd89462ea508b69 (diff)
downloadgcc-4df6a9063433b4f47a2f49535b448408a9dd6b94.zip
gcc-4df6a9063433b4f47a2f49535b448408a9dd6b94.tar.gz
gcc-4df6a9063433b4f47a2f49535b448408a9dd6b94.tar.bz2
re PR tree-optimization/88274 (ICE in check, at tree-vrp.c:188)
PR tree-optimization/88274 * tree-ssa-reassoc.c (optimize_range_tests_xor, optimize_range_tests_diff): If type has smaller precision than corresponding mode or if it has non-standard min/max, compute everything in a standard type for the precision. From-SVN: r266701
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-ssa-reassoc.c28
2 files changed, 32 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f319daf..a759eeb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2018-11-30 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/88274
+ * tree-ssa-reassoc.c (optimize_range_tests_xor,
+ optimize_range_tests_diff): If type has smaller precision than
+ corresponding mode or if it has non-standard min/max, compute
+ everything in a standard type for the precision.
+
PR testsuite/85368
* params.def (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT): New param.
* tree-ssa-ifcombine.c (ifcombine_ifandif): If
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 971d926e..a9f45bf 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2537,8 +2537,23 @@ optimize_range_tests_xor (enum tree_code opcode, tree type,
if (!tree_int_cst_equal (lowxor, highxor))
return false;
+ exp = rangei->exp;
+ scalar_int_mode mode = as_a <scalar_int_mode> (TYPE_MODE (type));
+ int prec = GET_MODE_PRECISION (mode);
+ if (TYPE_PRECISION (type) < prec
+ || (wi::to_wide (TYPE_MIN_VALUE (type))
+ != wi::min_value (prec, TYPE_SIGN (type)))
+ || (wi::to_wide (TYPE_MAX_VALUE (type))
+ != wi::max_value (prec, TYPE_SIGN (type))))
+ {
+ type = build_nonstandard_integer_type (prec, TYPE_UNSIGNED (type));
+ exp = fold_convert (type, exp);
+ lowxor = fold_convert (type, lowxor);
+ lowi = fold_convert (type, lowi);
+ highi = fold_convert (type, highi);
+ }
tem = fold_build1 (BIT_NOT_EXPR, type, lowxor);
- exp = fold_build2 (BIT_AND_EXPR, type, rangei->exp, tem);
+ exp = fold_build2 (BIT_AND_EXPR, type, exp, tem);
lowj = fold_build2 (BIT_AND_EXPR, type, lowi, tem);
highj = fold_build2 (BIT_AND_EXPR, type, highi, tem);
if (update_range_test (rangei, rangej, NULL, 1, opcode, ops, exp,
@@ -2581,7 +2596,16 @@ optimize_range_tests_diff (enum tree_code opcode, tree type,
if (!integer_pow2p (tem1))
return false;
- type = unsigned_type_for (type);
+ scalar_int_mode mode = as_a <scalar_int_mode> (TYPE_MODE (type));
+ int prec = GET_MODE_PRECISION (mode);
+ if (TYPE_PRECISION (type) < prec
+ || (wi::to_wide (TYPE_MIN_VALUE (type))
+ != wi::min_value (prec, TYPE_SIGN (type)))
+ || (wi::to_wide (TYPE_MAX_VALUE (type))
+ != wi::max_value (prec, TYPE_SIGN (type))))
+ type = build_nonstandard_integer_type (prec, 1);
+ else
+ type = unsigned_type_for (type);
tem1 = fold_convert (type, tem1);
tem2 = fold_convert (type, tem2);
lowi = fold_convert (type, lowi);