From: Jakub Jelinek Date: Mon, 21 Oct 2019 11:36:36 +0000 (+0200) Subject: backport: re PR go/91617 (Many go test case failures after r275026) X-Git-Tag: releases/gcc-9.3.0~524 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56131f53b9b712d79344824ecd6a8b83d1c808a2;p=thirdparty%2Fgcc.git backport: re PR go/91617 (Many go test case failures after r275026) Backported from mainline 2019-09-02 Jakub Jelinek PR go/91617 * fold-const.c (range_check_type): For enumeral and boolean type, pass 1 to type_for_size langhook instead of TYPE_UNSIGNED (etype). Return unsigned_type_for result whenever etype isn't TYPE_UNSIGNED INTEGER_TYPE. (build_range_check): Don't call unsigned_type_for for pointer types. * match.pd (X / C1 op C2): Don't call unsigned_type_for on range_check_type result. 2019-08-29 Jakub Jelinek PR tree-optimization/91351 * tree-cfg.c (generate_range_test): Use range_check_type instead of unsigned_type_for. * tree-cfgcleanup.c (convert_single_case_switch): Punt if range_check_type returns NULL. * tree-switch-conversion.c (switch_conversion::build_one_array): Use range_check_type instead of unsigned_type_for, don't perform linear opt if it returns NULL. (bit_test_cluster::find_bit_tests): Formatting fix. (bit_test_cluster::emit): Use range_check_type instead of unsigned_type_for. (switch_decision_tree::try_switch_expansion): Punt if range_check_type returns NULL. * g++.dg/opt/pr91351.C: New test. From-SVN: r277244 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca0db0bce345..7242fd804a16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2019-10-21 Jakub Jelinek + + Backported from mainline + 2019-09-02 Jakub Jelinek + + PR go/91617 + * fold-const.c (range_check_type): For enumeral and boolean + type, pass 1 to type_for_size langhook instead of + TYPE_UNSIGNED (etype). Return unsigned_type_for result whenever + etype isn't TYPE_UNSIGNED INTEGER_TYPE. + (build_range_check): Don't call unsigned_type_for for pointer types. + * match.pd (X / C1 op C2): Don't call unsigned_type_for on + range_check_type result. + + 2019-08-29 Jakub Jelinek + + PR tree-optimization/91351 + * tree-cfg.c (generate_range_test): Use range_check_type instead of + unsigned_type_for. + * tree-cfgcleanup.c (convert_single_case_switch): Punt if + range_check_type returns NULL. + * tree-switch-conversion.c (switch_conversion::build_one_array): + Use range_check_type instead of unsigned_type_for, don't perform + linear opt if it returns NULL. + (bit_test_cluster::find_bit_tests): Formatting fix. + (bit_test_cluster::emit): Use range_check_type instead of + unsigned_type_for. + (switch_decision_tree::try_switch_expansion): Punt if range_check_type + returns NULL. + 2019-10-18 Georg-Johann Lay Backport from 2019-10-18 trunk r277143. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f0e43b5fda23..9feaea9fde57 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4935,10 +4935,9 @@ range_check_type (tree etype) /* First make sure that arithmetics in this type is valid, then make sure that it wraps around. */ if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE) - etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), - TYPE_UNSIGNED (etype)); + etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1); - if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype)) + if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (etype)) { tree utype, minv, maxv; @@ -4956,6 +4955,8 @@ range_check_type (tree etype) else return NULL_TREE; } + else if (POINTER_TYPE_P (etype)) + etype = unsigned_type_for (etype); return etype; } @@ -5046,9 +5047,6 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, if (etype == NULL_TREE) return NULL_TREE; - if (POINTER_TYPE_P (etype)) - etype = unsigned_type_for (etype); - high = fold_convert_loc (loc, etype, high); low = fold_convert_loc (loc, etype, low); exp = fold_convert_loc (loc, etype, exp); diff --git a/gcc/match.pd b/gcc/match.pd index 039ddacfed1e..533082196a2f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1519,8 +1519,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) tree etype = range_check_type (TREE_TYPE (@0)); if (etype) { - if (! TYPE_UNSIGNED (etype)) - etype = unsigned_type_for (etype); hi = fold_convert (etype, hi); lo = fold_convert (etype, lo); hi = const_binop (MINUS_EXPR, etype, hi, lo); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 84aaff446694..6b55e4372313 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2019-10-21 Jakub Jelinek Backported from mainline + 2019-08-29 Jakub Jelinek + + PR tree-optimization/91351 + * g++.dg/opt/pr91351.C: New test. + 2019-08-09 Jakub Jelinek PR c/91401 diff --git a/gcc/testsuite/g++.dg/opt/pr91351.C b/gcc/testsuite/g++.dg/opt/pr91351.C new file mode 100644 index 000000000000..f793a2f1b117 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr91351.C @@ -0,0 +1,38 @@ +// PR tree-optimization/91351 +// { dg-do run } +// { dg-options "-O2 -fstrict-enums" } + +enum E { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, + e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25 }; + +__attribute__((noipa)) void +foo () +{ + __builtin_abort (); +} + +__attribute__((noipa)) void +bar () +{ +} + +__attribute__((noipa)) void +baz (E e) +{ + switch (e) + { + case e11: + case e12: + case e13: foo (); break; + case e24: break; + case e14: + case e15: break; + default: bar (); break; + } +} + +int +main () +{ + baz (e3); +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 32be59acfb06..d27cc65f8837 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -9151,7 +9151,7 @@ generate_range_test (basic_block bb, tree index, tree low, tree high, tree *lhs, tree *rhs) { tree type = TREE_TYPE (index); - tree utype = unsigned_type_for (type); + tree utype = range_check_type (type); low = fold_convert (utype, low); high = fold_convert (utype, high); diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 183b491ab1d3..4bac38ab00c7 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -101,6 +101,8 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi) if (high) { tree lhs, rhs; + if (range_check_type (TREE_TYPE (index)) == NULL_TREE) + return false; generate_range_test (bb, index, low, high, &lhs, &rhs); cond = gimple_build_cond (LE_EXPR, lhs, rhs, NULL_TREE, NULL_TREE); } diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index c3f2baf39d70..dd6dd8064de4 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -605,7 +605,9 @@ switch_conversion::build_one_array (int num, tree arr_index_type, vec *constructor = m_constructors[num]; wide_int coeff_a, coeff_b; bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b); - if (linear_p) + tree type; + if (linear_p + && (type = range_check_type (TREE_TYPE ((*constructor)[0].value)))) { if (dump_file && coeff_a.to_uhwi () > 0) fprintf (dump_file, "Linear transformation with A = %" PRId64 @@ -613,13 +615,12 @@ switch_conversion::build_one_array (int num, tree arr_index_type, coeff_b.to_shwi ()); /* We must use type of constructor values. */ - tree t = unsigned_type_for (TREE_TYPE ((*constructor)[0].value)); gimple_seq seq = NULL; - tree tmp = gimple_convert (&seq, t, m_index_expr); - tree tmp2 = gimple_build (&seq, MULT_EXPR, t, - wide_int_to_tree (t, coeff_a), tmp); - tree tmp3 = gimple_build (&seq, PLUS_EXPR, t, tmp2, - wide_int_to_tree (t, coeff_b)); + tree tmp = gimple_convert (&seq, type, m_index_expr); + tree tmp2 = gimple_build (&seq, MULT_EXPR, type, + wide_int_to_tree (type, coeff_a), tmp); + tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2, + wide_int_to_tree (type, coeff_b)); tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3); gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); load = gimple_build_assign (name, tmp4); @@ -1350,7 +1351,7 @@ bit_test_cluster::find_bit_tests (vec &clusters) entire)); } else - for (int i = end - 1; i >= start; i--) + for (int i = end - 1; i >= start; i--) output.safe_push (clusters[i]); end = start; @@ -1483,7 +1484,7 @@ bit_test_cluster::emit (tree index_expr, tree index_type, unsigned int i, j, k; unsigned int count; - tree unsigned_index_type = unsigned_type_for (index_type); + tree unsigned_index_type = range_check_type (index_type); gimple_stmt_iterator gsi; gassign *shift_stmt; @@ -1793,7 +1794,8 @@ switch_decision_tree::try_switch_expansion (vec &clusters) tree index_type = TREE_TYPE (index_expr); basic_block bb = gimple_bb (m_switch); - if (gimple_switch_num_labels (m_switch) == 1) + if (gimple_switch_num_labels (m_switch) == 1 + || range_check_type (index_type) == NULL_TREE) return false; /* Find the default case target label. */