This also fixes the type of the irange used for unswitching of switch statements.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/105802 * tree-ssa-loop-unswitch.cc (find_unswitching_predicates_for_bb): Make sure to also compute the range in the type of the switch index. * g++.dg/opt/pr105802.C: New testcase. --- gcc/testsuite/g++.dg/opt/pr105802.C | 23 +++++++++++++++++++++++ gcc/tree-ssa-loop-unswitch.cc | 17 +++++++---------- 2 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr105802.C diff --git a/gcc/testsuite/g++.dg/opt/pr105802.C b/gcc/testsuite/g++.dg/opt/pr105802.C new file mode 100644 index 00000000000..2514245d00a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr105802.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O3" } + +enum E { E0, E1 }; + +void bar (); +void baz (); + +int c; + +void +foo (int i) +{ + E e = (E) i; + while (c) + switch (e) + { + case E0: + bar (); + case E1: + baz (); + } +} diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc index 2b6013e9d69..61c04ed9f2e 100644 --- a/gcc/tree-ssa-loop-unswitch.cc +++ b/gcc/tree-ssa-loop-unswitch.cc @@ -523,22 +523,19 @@ find_unswitching_predicates_for_bb (basic_block bb, class loop *loop, tree lab = gimple_switch_label (stmt, i); tree cmp; int_range<2> lab_range; + tree low = fold_convert (idx_type, CASE_LOW (lab)); if (CASE_HIGH (lab) != NULL_TREE) { - tree cmp1 = fold_build2 (GE_EXPR, boolean_type_node, idx, - fold_convert (idx_type, - CASE_LOW (lab))); - tree cmp2 = fold_build2 (LE_EXPR, boolean_type_node, idx, - fold_convert (idx_type, - CASE_HIGH (lab))); + tree high = fold_convert (idx_type, CASE_HIGH (lab)); + tree cmp1 = fold_build2 (GE_EXPR, boolean_type_node, idx, low); + tree cmp2 = fold_build2 (LE_EXPR, boolean_type_node, idx, high); cmp = fold_build2 (BIT_AND_EXPR, boolean_type_node, cmp1, cmp2); - lab_range.set (CASE_LOW (lab), CASE_HIGH (lab)); + lab_range.set (low, high); } else { - cmp = fold_build2 (EQ_EXPR, boolean_type_node, idx, - fold_convert (idx_type, CASE_LOW (lab))); - lab_range.set (CASE_LOW (lab)); + cmp = fold_build2 (EQ_EXPR, boolean_type_node, idx, low); + lab_range.set (low); } /* Combine the expression with the existing one. */ -- 2.35.3