From 90aead2189d5af665c4d7616ea39b8aa7c2d98ce Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Sat, 14 Jan 2017 09:52:18 -0700 Subject: [PATCH] re PR rtl-optimization/78626 (ICE in rtl_verify_bb_insns, at cfgrtl.c:2656 (error: flow control insn inside a basic block)) PR rtl-optimization/78626 PR rtl-optimization/78727 * cprop.c (one_cprop_pass): Collect unconditional traps in the middle of a block, and split such blocks after everything else is finished. PR rtl-optimization/78626 PR rtl-optimization/78727 * gcc.dg/torture/pr78626.c: New test. * gcc.dg/torture/pr78727.c: New test. From-SVN: r244467 --- gcc/ChangeLog | 7 +++++++ gcc/cprop.c | 25 +++++++++++++++++++++++- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/torture/pr78626.c | 27 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr78727.c | 21 ++++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr78626.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr78727.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 910605368d3..746f6af65ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-01-14 Bernd Schmidt + + PR rtl-optimization/78626 + PR rtl-optimization/78727 + * cprop.c (one_cprop_pass): Collect unconditional traps in the middle + of a block, and split such blocks after everything else is finished. + 2017-01-14 Alan Modra PR target/72749 diff --git a/gcc/cprop.c b/gcc/cprop.c index b210e944f84..b6c2bc431fd 100644 --- a/gcc/cprop.c +++ b/gcc/cprop.c @@ -1794,7 +1794,7 @@ one_cprop_pass (void) if (set_hash_table.n_elems > 0) { basic_block bb; - rtx_insn *insn; + auto_vec uncond_traps; alloc_cprop_mem (last_basic_block_for_fn (cfun), set_hash_table.n_elems); @@ -1810,6 +1810,9 @@ one_cprop_pass (void) EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) { + bool seen_uncond_trap = false; + rtx_insn *insn; + /* Reset tables used to keep track of what's still valid [since the start of the block]. */ reset_opr_set_tables (); @@ -1817,6 +1820,10 @@ one_cprop_pass (void) FOR_BB_INSNS (bb, insn) if (INSN_P (insn)) { + bool was_uncond_trap + = (GET_CODE (PATTERN (insn)) == TRAP_IF + && XEXP (PATTERN (insn), 0) == const1_rtx); + changed |= cprop_insn (insn); /* Keep track of everything modified by this insn. */ @@ -1825,11 +1832,27 @@ one_cprop_pass (void) insn into a NOTE, or deleted the insn. */ if (! NOTE_P (insn) && ! insn->deleted ()) mark_oprs_set (insn); + + if (!was_uncond_trap && !seen_uncond_trap + && GET_CODE (PATTERN (insn)) == TRAP_IF + && XEXP (PATTERN (insn), 0) == const1_rtx) + { + seen_uncond_trap = true; + uncond_traps.safe_push (insn); + } } } changed |= bypass_conditional_jumps (); + while (!uncond_traps.is_empty ()) + { + rtx_insn *insn = uncond_traps.pop (); + basic_block to_split = BLOCK_FOR_INSN (insn); + remove_edge (split_block (to_split, insn)); + emit_barrier_after_bb (to_split); + } + FREE_REG_SET (reg_set_bitmap); free_cprop_mem (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 70ccd17ba72..625c99a7d22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-01-14 Bernd Schmidt + + PR rtl-optimization/78626 + PR rtl-optimization/78727 + * gcc.dg/torture/pr78626.c: New test. + * gcc.dg/torture/pr78727.c: New test. + 2017-01-14 Alan Modra * gcc.c-torture/compile/pr72749.c: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr78626.c b/gcc/testsuite/gcc.dg/torture/pr78626.c new file mode 100644 index 00000000000..ed4775a7f8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78626.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +int qs; + +void +ms (int g1) +{ + int cy; + int *fr = &cy; + + for (;;) + { + *fr = 1; + fr = &g1; + + while (qs != 0) + { + if (qs | cy) + qs = g1 / 0; /* { dg-warning "division" } */ + ++qs; + } + + cy = 1; + while (cy != 0) + cy = 2; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr78727.c b/gcc/testsuite/gcc.dg/torture/pr78727.c new file mode 100644 index 00000000000..93cc3d72972 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78727.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int +dd (int gj, unsigned int o7) +{ + long long int e8 = gj; + + e8 |= gj + 1u; + if (e8 != 0) + { + short int *mn = (short int *)&e8; + int pv; + + e8 &= e8 > gj; + gj = o7 > e8; + pv = ((gj != 0) ? gj : *mn) && e8; + gj |= *mn / pv; + } + + return gj; +} -- 2.30.2