re PR testsuite/48809 (switch statement optimization error)
PR tree-optimization/48809 * tree-switch-conversion.c (build_arrays): Compute tidx in unsigned type. (gen_inbound_check): Don't compute index_expr - range_min in utype again, instead reuse SSA_NAME initialized in build_arrays. Remove two useless gsi_for_stmt calls. * gcc.c-torture/execute/pr48809.c: New test. From-SVN: r173207
This commit is contained in:
parent
a6545a3d94
commit
edb9b69e57
@ -1,3 +1,12 @@
|
||||
2011-04-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/48809
|
||||
* tree-switch-conversion.c (build_arrays): Compute tidx in unsigned
|
||||
type.
|
||||
(gen_inbound_check): Don't compute index_expr - range_min in utype
|
||||
again, instead reuse SSA_NAME initialized in build_arrays.
|
||||
Remove two useless gsi_for_stmt calls.
|
||||
|
||||
2011-04-29 Jeff Law <law@redhat.com>
|
||||
|
||||
* tree-ssa-threadedge.c (thread_across_edge): Add missing return.
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-04-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/48809
|
||||
* gcc.c-torture/execute/pr48809.c: New test.
|
||||
|
||||
2011-04-29 Jeff Law <law@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: New test.
|
||||
|
60
gcc/testsuite/gcc.c-torture/execute/pr48809.c
Normal file
60
gcc/testsuite/gcc.c-torture/execute/pr48809.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* PR tree-optimization/48809 */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
foo (signed char x)
|
||||
{
|
||||
int y = 0;
|
||||
switch (x)
|
||||
{
|
||||
case 0: y = 1; break;
|
||||
case 1: y = 7; break;
|
||||
case 2: y = 2; break;
|
||||
case 3: y = 19; break;
|
||||
case 4: y = 5; break;
|
||||
case 5: y = 17; break;
|
||||
case 6: y = 31; break;
|
||||
case 7: y = 8; break;
|
||||
case 8: y = 28; break;
|
||||
case 9: y = 16; break;
|
||||
case 10: y = 31; break;
|
||||
case 11: y = 12; break;
|
||||
case 12: y = 15; break;
|
||||
case 13: y = 111; break;
|
||||
case 14: y = 17; break;
|
||||
case 15: y = 10; break;
|
||||
case 16: y = 31; break;
|
||||
case 17: y = 7; break;
|
||||
case 18: y = 2; break;
|
||||
case 19: y = 19; break;
|
||||
case 20: y = 5; break;
|
||||
case 21: y = 107; break;
|
||||
case 22: y = 31; break;
|
||||
case 23: y = 8; break;
|
||||
case 24: y = 28; break;
|
||||
case 25: y = 106; break;
|
||||
case 26: y = 31; break;
|
||||
case 27: y = 102; break;
|
||||
case 28: y = 105; break;
|
||||
case 29: y = 111; break;
|
||||
case 30: y = 17; break;
|
||||
case 31: y = 10; break;
|
||||
case 32: y = 31; break;
|
||||
case 98: y = 18; break;
|
||||
case -62: y = 19; break;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (foo (98) != 18 || foo (97) != 0 || foo (99) != 0)
|
||||
abort ();
|
||||
if (foo (-62) != 19 || foo (-63) != 0 || foo (-61) != 0)
|
||||
abort ();
|
||||
if (foo (28) != 105 || foo (27) != 102 || foo (29) != 111)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/* Switch Conversion converts variable initializations based on switch
|
||||
statements to initializations from a static array.
|
||||
Copyright (C) 2006, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Martin Jambor <jamborm@suse.cz>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -656,7 +656,7 @@ static void
|
||||
build_arrays (gimple swtch)
|
||||
{
|
||||
tree arr_index_type;
|
||||
tree tidx, sub, tmp;
|
||||
tree tidx, sub, tmp, utype;
|
||||
gimple stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
int i;
|
||||
@ -664,14 +664,20 @@ build_arrays (gimple swtch)
|
||||
|
||||
gsi = gsi_for_stmt (swtch);
|
||||
|
||||
/* Make sure we do not generate arithmetics in a subrange. */
|
||||
utype = TREE_TYPE (info.index_expr);
|
||||
if (TREE_TYPE (utype))
|
||||
utype = lang_hooks.types.type_for_mode (TYPE_MODE (TREE_TYPE (utype)), 1);
|
||||
else
|
||||
utype = lang_hooks.types.type_for_mode (TYPE_MODE (utype), 1);
|
||||
|
||||
arr_index_type = build_index_type (info.range_size);
|
||||
tmp = create_tmp_var (TREE_TYPE (info.index_expr), "csti");
|
||||
tmp = create_tmp_var (utype, "csui");
|
||||
add_referenced_var (tmp);
|
||||
tidx = make_ssa_name (tmp, NULL);
|
||||
sub = fold_build2_loc (loc, MINUS_EXPR,
|
||||
TREE_TYPE (info.index_expr), info.index_expr,
|
||||
fold_convert_loc (loc, TREE_TYPE (info.index_expr),
|
||||
info.range_min));
|
||||
sub = fold_build2_loc (loc, MINUS_EXPR, utype,
|
||||
fold_convert_loc (loc, utype, info.index_expr),
|
||||
fold_convert_loc (loc, utype, info.range_min));
|
||||
sub = force_gimple_operand_gsi (&gsi, sub,
|
||||
false, NULL, true, GSI_SAME_STMT);
|
||||
stmt = gimple_build_assign (tidx, sub);
|
||||
@ -780,12 +786,7 @@ gen_inbound_check (gimple swtch)
|
||||
tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
tree label_decl3 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gimple label1, label2, label3;
|
||||
|
||||
tree utype;
|
||||
tree tmp_u_1, tmp_u_2, tmp_u_var;
|
||||
tree cast;
|
||||
gimple cast_assign, minus_assign;
|
||||
tree ulb, minus;
|
||||
tree utype, tidx;
|
||||
tree bound;
|
||||
|
||||
gimple cond_stmt;
|
||||
@ -799,49 +800,24 @@ gen_inbound_check (gimple swtch)
|
||||
gcc_assert (info.default_values);
|
||||
bb0 = gimple_bb (swtch);
|
||||
|
||||
/* Make sure we do not generate arithmetics in a subrange. */
|
||||
if (TREE_TYPE (TREE_TYPE (info.index_expr)))
|
||||
utype = lang_hooks.types.type_for_mode
|
||||
(TYPE_MODE (TREE_TYPE (TREE_TYPE (info.index_expr))), 1);
|
||||
else
|
||||
utype = lang_hooks.types.type_for_mode
|
||||
(TYPE_MODE (TREE_TYPE (info.index_expr)), 1);
|
||||
tidx = gimple_assign_lhs (info.arr_ref_first);
|
||||
utype = TREE_TYPE (tidx);
|
||||
|
||||
/* (end of) block 0 */
|
||||
gsi = gsi_for_stmt (info.arr_ref_first);
|
||||
tmp_u_var = create_tmp_var (utype, "csui");
|
||||
add_referenced_var (tmp_u_var);
|
||||
tmp_u_1 = make_ssa_name (tmp_u_var, NULL);
|
||||
|
||||
cast = fold_convert_loc (loc, utype, info.index_expr);
|
||||
cast_assign = gimple_build_assign (tmp_u_1, cast);
|
||||
SSA_NAME_DEF_STMT (tmp_u_1) = cast_assign;
|
||||
gsi_insert_before (&gsi, cast_assign, GSI_SAME_STMT);
|
||||
update_stmt (cast_assign);
|
||||
|
||||
ulb = fold_convert_loc (loc, utype, info.range_min);
|
||||
minus = fold_build2_loc (loc, MINUS_EXPR, utype, tmp_u_1, ulb);
|
||||
minus = force_gimple_operand_gsi (&gsi, minus, false, NULL, true,
|
||||
GSI_SAME_STMT);
|
||||
tmp_u_2 = make_ssa_name (tmp_u_var, NULL);
|
||||
minus_assign = gimple_build_assign (tmp_u_2, minus);
|
||||
SSA_NAME_DEF_STMT (tmp_u_2) = minus_assign;
|
||||
gsi_insert_before (&gsi, minus_assign, GSI_SAME_STMT);
|
||||
update_stmt (minus_assign);
|
||||
gsi_next (&gsi);
|
||||
|
||||
bound = fold_convert_loc (loc, utype, info.range_size);
|
||||
cond_stmt = gimple_build_cond (LE_EXPR, tmp_u_2, bound, NULL_TREE, NULL_TREE);
|
||||
cond_stmt = gimple_build_cond (LE_EXPR, tidx, bound, NULL_TREE, NULL_TREE);
|
||||
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
|
||||
update_stmt (cond_stmt);
|
||||
|
||||
/* block 2 */
|
||||
gsi = gsi_for_stmt (info.arr_ref_first);
|
||||
label2 = gimple_build_label (label_decl2);
|
||||
gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
|
||||
last_assign = gen_def_assigns (&gsi);
|
||||
|
||||
/* block 1 */
|
||||
gsi = gsi_for_stmt (info.arr_ref_first);
|
||||
label1 = gimple_build_label (label_decl1);
|
||||
gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user