aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-06-01 15:42:06 +0200
committerRichard Biener <rguenther@suse.de>2022-06-02 08:35:23 +0200
commit4a6b8d9aad9f68eec223cc126d9effbf45e37271 (patch)
tree9facd460dc0d8d3ad5ad0ac3918844ccb2a5866b
parent3164de6ac1b8473e60f6b85e94b15930694c80d7 (diff)
downloadgcc-4a6b8d9aad9f68eec223cc126d9effbf45e37271.zip
gcc-4a6b8d9aad9f68eec223cc126d9effbf45e37271.tar.gz
gcc-4a6b8d9aad9f68eec223cc126d9effbf45e37271.tar.bz2
tree-optimization/105802 - another unswitching type issue
This also fixes the type of the irange used for unswitching of switch statements. 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.
-rw-r--r--gcc/testsuite/g++.dg/opt/pr105802.C23
-rw-r--r--gcc/tree-ssa-loop-unswitch.cc17
2 files changed, 30 insertions, 10 deletions
diff --git a/gcc/testsuite/g++.dg/opt/pr105802.C b/gcc/testsuite/g++.dg/opt/pr105802.C
new file mode 100644
index 0000000..2514245
--- /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 2b6013e..61c04ed 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. */