diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-12-01 00:27:23 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-12-01 00:27:23 +0100 |
commit | 4df6a9063433b4f47a2f49535b448408a9dd6b94 (patch) | |
tree | 192c96fb9b81b88f5c5727e9b4e6f1b331f4986c /gcc | |
parent | e26584b265dc2af4e95d23c4bdd89462ea508b69 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 28 |
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); |