diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-08-29 11:20:54 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-08-29 11:20:54 +0200 |
commit | 1d9cd701ec31686dbd037e0fe264c8738d993e41 (patch) | |
tree | c21d3fa2978d3c7b2e588a5c894f40a108b0f09d /gcc/tree-switch-conversion.c | |
parent | c3bad34748071038343f8b88a30128faee7c5c0c (diff) | |
download | gcc-1d9cd701ec31686dbd037e0fe264c8738d993e41.zip gcc-1d9cd701ec31686dbd037e0fe264c8738d993e41.tar.gz gcc-1d9cd701ec31686dbd037e0fe264c8738d993e41.tar.bz2 |
re PR tree-optimization/91351 (-fstrict-enums generates incorrect code)
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: r275026
Diffstat (limited to 'gcc/tree-switch-conversion.c')
-rw-r--r-- | gcc/tree-switch-conversion.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 776db77..e8692a7 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_elt, va_gc> *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); @@ -1351,7 +1352,7 @@ bit_test_cluster::find_bit_tests (vec<cluster *> &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; @@ -1484,7 +1485,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; @@ -1794,7 +1795,8 @@ switch_decision_tree::try_switch_expansion (vec<cluster *> &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. */ |