Commit 7b4cae1b by Richard Biener Committed by Richard Biener

tree-ssa-forwprop.c (simplify_gimple_switch): Enhance check for which sign-changes we allow when...

2014-04-14  Richard Biener  <rguenther@suse.de>

	* tree-ssa-forwprop.c (simplify_gimple_switch): Enhance
	check for which sign-changes we allow when forwarding
	a converted value into a switch.

	* g++.dg/tree-ssa/forwprop-switch.C: New testcase.

From-SVN: r209372
parent 4116e7d0
2014-04-14 Richard Biener <rguenther@suse.de>
* tree-ssa-forwprop.c (simplify_gimple_switch): Enhance
check for which sign-changes we allow when forwarding
a converted value into a switch.
2014-04-14 Eric Botcazou <ebotcazou@adacore.com> 2014-04-14 Eric Botcazou <ebotcazou@adacore.com>
* stor-layout.c (place_field): Finalize non-constant offset for the * stor-layout.c (place_field): Finalize non-constant offset for the
......
2014-04-14 Richard Biener <rguenther@suse.de>
* g++.dg/tree-ssa/forwprop-switch.C: New testcase.
2014-04-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2014-04-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc.dg/lto/pr55113_0.c: Skip on i?86-*-solaris2.1[0-1]*. * gcc.dg/lto/pr55113_0.c: Skip on i?86-*-solaris2.1[0-1]*.
......
// { dg-do compile }
// { dg-options "-O -fdump-tree-cddce1" }
enum Scale { E1, E2, E3, E4, E5, E6, E7, E8 };
int Test(Scale s)
{
switch(s)
{
case E1: return 12;
case E2: return 17;
case E3: return 22;
case E4: return 42;
default: break;
}
return 0;
}
// tree forwprop should have eliminated the (int) s cast for the
// switch value and directly switch on the 's' parameter
// { dg-final { scan-tree-dump-not "\\\(int\\\)" "cddce1" } }
// { dg-final { scan-tree-dump "switch \\\(s_.\\\(D\\\)\\\)" "cddce1" } }
// { dg-final { cleanup-tree-dump "cddce1" } }
...@@ -1356,43 +1356,38 @@ simplify_gimple_switch_label_vec (gimple stmt, tree index_type) ...@@ -1356,43 +1356,38 @@ simplify_gimple_switch_label_vec (gimple stmt, tree index_type)
static bool static bool
simplify_gimple_switch (gimple stmt) simplify_gimple_switch (gimple stmt)
{ {
tree cond = gimple_switch_index (stmt);
tree def, to, ti;
gimple def_stmt;
/* The optimization that we really care about is removing unnecessary /* The optimization that we really care about is removing unnecessary
casts. That will let us do much better in propagating the inferred casts. That will let us do much better in propagating the inferred
constant at the switch target. */ constant at the switch target. */
tree cond = gimple_switch_index (stmt);
if (TREE_CODE (cond) == SSA_NAME) if (TREE_CODE (cond) == SSA_NAME)
{ {
def_stmt = SSA_NAME_DEF_STMT (cond); gimple def_stmt = SSA_NAME_DEF_STMT (cond);
if (is_gimple_assign (def_stmt)) if (gimple_assign_cast_p (def_stmt))
{ {
if (gimple_assign_rhs_code (def_stmt) == NOP_EXPR) tree def = gimple_assign_rhs1 (def_stmt);
{ if (TREE_CODE (def) != SSA_NAME)
int need_precision; return false;
bool fail;
def = gimple_assign_rhs1 (def_stmt);
to = TREE_TYPE (cond);
ti = TREE_TYPE (def);
/* If we have an extension that preserves value, then we
can copy the source value into the switch. */
need_precision = TYPE_PRECISION (ti);
fail = false;
if (! INTEGRAL_TYPE_P (ti))
fail = true;
else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
fail = true;
else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
need_precision += 1;
if (TYPE_PRECISION (to) < need_precision)
fail = true;
if (!fail) /* If we have an extension or sign-change that preserves the
values we check against then we can copy the source value into
the switch. */
tree ti = TREE_TYPE (def);
if (INTEGRAL_TYPE_P (ti)
&& TYPE_PRECISION (ti) <= TYPE_PRECISION (TREE_TYPE (cond)))
{
size_t n = gimple_switch_num_labels (stmt);
tree min = NULL_TREE, max = NULL_TREE;
if (n > 1)
{
min = CASE_LOW (gimple_switch_label (stmt, 1));
if (CASE_HIGH (gimple_switch_label (stmt, n - 1)))
max = CASE_HIGH (gimple_switch_label (stmt, n - 1));
else
max = CASE_LOW (gimple_switch_label (stmt, n - 1));
}
if ((!min || int_fits_type_p (min, ti))
&& (!max || int_fits_type_p (max, ti)))
{ {
gimple_switch_set_index (stmt, def); gimple_switch_set_index (stmt, def);
simplify_gimple_switch_label_vec (stmt, ti); simplify_gimple_switch_label_vec (stmt, ti);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment