--- /dev/null
+/* 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;
+}
build_arrays (gimple swtch)
{
tree arr_index_type;
- tree tidx, sub;
+ tree tidx, sub, utype;
gimple stmt;
gimple_stmt_iterator gsi;
int i;
gsi = gsi_for_stmt (swtch);
arr_index_type = build_index_type (info.range_size);
- tidx = make_rename_temp (arr_index_type, "csti");
- sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
- fold_convert (TREE_TYPE (info.index_expr),
- info.range_min));
- sub = force_gimple_operand_gsi (&gsi, fold_convert (arr_index_type, sub),
- false, NULL, true, GSI_SAME_STMT);
+
+ /* 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 = make_rename_temp (utype, "csui");
+ sub = fold_build2 (MINUS_EXPR, utype,
+ fold_convert (utype, info.index_expr),
+ fold_convert (utype, info.range_min));
+ sub = force_gimple_operand_gsi (&gsi, sub, false, NULL, true, GSI_SAME_STMT);
stmt = gimple_build_assign (tidx, sub);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
gimple label1, label2, label3;
tree utype;
- tree tmp_u;
- tree cast;
- gimple cast_assign, minus_assign;
- tree ulb, minus;
+ tree tidx;
tree bound;
gimple cond_stmt;
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 = make_rename_temp (utype, "csui");
-
- cast = fold_convert (utype, info.index_expr);
- cast_assign = gimple_build_assign (tmp_u, cast);
- find_new_referenced_vars (cast_assign);
- gsi_insert_before (&gsi, cast_assign, GSI_SAME_STMT);
- mark_symbols_for_renaming (cast_assign);
-
- ulb = fold_convert (utype, info.range_min);
- minus = fold_build2 (MINUS_EXPR, utype, tmp_u, ulb);
- minus = force_gimple_operand_gsi (&gsi, minus, false, NULL, true,
- GSI_SAME_STMT);
- minus_assign = gimple_build_assign (tmp_u, minus);
- find_new_referenced_vars (minus_assign);
- gsi_insert_before (&gsi, minus_assign, GSI_SAME_STMT);
- mark_symbols_for_renaming (minus_assign);
+ gsi_next (&gsi);
bound = fold_convert (utype, info.range_size);
- cond_stmt = gimple_build_cond (LE_EXPR, tmp_u, bound, NULL_TREE, NULL_TREE);
+ cond_stmt = gimple_build_cond (LE_EXPR, tidx, bound, NULL_TREE, NULL_TREE);
find_new_referenced_vars (cond_stmt);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
mark_symbols_for_renaming (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);