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.
This commit is contained in:
Richard Biener
2022-06-01 15:42:06 +02:00
parent 3164de6ac1
commit 4a6b8d9aad
2 changed files with 30 additions and 10 deletions

View File

@@ -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 ();
}
}

View File

@@ -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. */