aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-switch-conversion.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-08-29 11:20:54 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-08-29 11:20:54 +0200
commit1d9cd701ec31686dbd037e0fe264c8738d993e41 (patch)
treec21d3fa2978d3c7b2e588a5c894f40a108b0f09d /gcc/tree-switch-conversion.c
parentc3bad34748071038343f8b88a30128faee7c5c0c (diff)
downloadgcc-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.c22
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. */