Second part of the patch set which omits one split_block (compared to the original patch). Acceptable just in case the first part will be accepted.
Thanks Martin
>From 2a9a8f11ea1ecd04c3b9915ff77fc791c55632da Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Tue, 29 Mar 2016 12:06:20 +0200 Subject: [PATCH 2/2] Fix PR hsa/70402 gcc/ChangeLog: 2016-03-29 Martin Liska <mli...@suse.cz> PR hsa/70402 * hsa-gen.c (gen_hsa_insns_for_switch_stmt): Guard index value that is really in range handled by SBR instruction. * hsa-brig.c (emit_switch_insn): Do not emit unconditional jump. * hsa-dump.c (dump_hsa_insn_1): Do not dump default BB. * hsa.h (hsa_insn_sbr::m_default_bb): Remove field. --- gcc/hsa-brig.c | 4 ---- gcc/hsa-dump.c | 3 --- gcc/hsa-gen.c | 45 +++++++++++++++++++++++++++++++++++++++------ gcc/hsa.h | 3 --- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c index 9b6c0b8..14c1d3f 100644 --- a/gcc/hsa-brig.c +++ b/gcc/hsa-brig.c @@ -1537,10 +1537,6 @@ emit_switch_insn (hsa_insn_sbr *sbr) brig_code.add (&repr, sizeof (repr)); brig_insn_count++; - - /* Emit jump to default label. */ - hsa_bb *hbb = hsa_bb_for_bb (sbr->m_default_bb); - emit_unconditional_jump (&hbb->m_label_ref); } /* Emit a HSA convert instruction and all necessary directives, schedule diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c index b69b34d..0885bc8 100644 --- a/gcc/hsa-dump.c +++ b/gcc/hsa-dump.c @@ -931,9 +931,6 @@ dump_hsa_insn_1 (FILE *f, hsa_insn_basic *insn, int *indent) if (i != sbr->m_jump_table.length () - 1) fprintf (f, ", "); } - - fprintf (f, "] /* default: BB %i */", - hsa_bb_for_bb (sbr->m_default_bb)->m_index); } else if (is_a <hsa_insn_arg_block *> (insn)) { diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 72eecf9..a8b868e 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -1530,7 +1530,7 @@ hsa_insn_br::operator new (size_t) hsa_insn_sbr::hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count) : hsa_insn_basic (1, BRIG_OPCODE_SBR, BRIG_TYPE_B1, index), - m_width (BRIG_WIDTH_1), m_jump_table (vNULL), m_default_bb (NULL), + m_width (BRIG_WIDTH_1), m_jump_table (vNULL), m_label_code_list (new hsa_op_code_list (jump_count)) { } @@ -3398,11 +3398,49 @@ get_switch_size (gswitch *s) static void gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb) { + gimple_stmt_iterator it = gsi_for_stmt (s); + gsi_prev (&it); + + /* Create preambule that verifies that index - lowest_label >= 0. */ + edge e = split_block (hbb->m_bb, gsi_stmt (it)); + e->flags &= ~EDGE_FALLTHRU; + e->flags |= EDGE_TRUE_VALUE; + function *func = DECL_STRUCT_FUNCTION (current_function_decl); tree index_tree = gimple_switch_index (s); tree lowest = get_switch_low (s); + tree highest = get_switch_high (s); hsa_op_reg *index = hsa_cfun->reg_for_gimple_ssa (index_tree); + + hsa_op_reg *cmp1_reg = new hsa_op_reg (BRIG_TYPE_B1); + hsa_op_immed *cmp1_immed = new hsa_op_immed (lowest); + hbb->append_insn (new hsa_insn_cmp (BRIG_COMPARE_GE, cmp1_reg->m_type, + cmp1_reg, index, cmp1_immed)); + + hsa_op_reg *cmp2_reg = new hsa_op_reg (BRIG_TYPE_B1); + hsa_op_immed *cmp2_immed = new hsa_op_immed (highest); + hbb->append_insn (new hsa_insn_cmp (BRIG_COMPARE_LE, cmp2_reg->m_type, + cmp2_reg, index, cmp2_immed)); + + hsa_op_reg *cmp_reg = new hsa_op_reg (BRIG_TYPE_B1); + hbb->append_insn (new hsa_insn_basic (3, BRIG_OPCODE_AND, cmp_reg->m_type, + cmp_reg, cmp1_reg, cmp2_reg)); + + hbb->append_insn (new hsa_insn_br (cmp_reg)); + + tree default_label = gimple_switch_default_label (s); + basic_block default_label_bb = label_to_block_fn (func, + CASE_LABEL (default_label)); + + make_edge (e->src, default_label_bb, EDGE_FALSE_VALUE); + + free_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_DOMINATORS); + + /* Basic block with the SBR instruction. */ + hbb = hsa_init_new_bb (e->dest); + hsa_op_reg *sub_index = new hsa_op_reg (index->m_type); hbb->append_insn (new hsa_insn_basic (3, BRIG_OPCODE_SUB, sub_index->m_type, sub_index, index, @@ -3414,11 +3452,6 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb) unsigned HOST_WIDE_INT size = tree_to_uhwi (get_switch_size (s)); hsa_insn_sbr *sbr = new hsa_insn_sbr (sub_index, size + 1); - tree default_label = gimple_switch_default_label (s); - basic_block default_label_bb = label_to_block_fn (func, - CASE_LABEL (default_label)); - - sbr->m_default_bb = default_label_bb; /* Prepare array with default label destination. */ for (unsigned HOST_WIDE_INT i = 0; i <= size; i++) diff --git a/gcc/hsa.h b/gcc/hsa.h index 1d6baab..1d55cef 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -562,9 +562,6 @@ public: /* Jump table. */ vec <basic_block> m_jump_table; - /* Default label basic block. */ - basic_block m_default_bb; - /* Code list for label references. */ hsa_op_code_list *m_label_code_list; -- 2.7.1