This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Missing barrier in outof_cfglayout
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: Steven Bosscher <stevenb dot gcc at gmail dot com>
- Cc: Jeff Law <law at redhat dot com>, GCC Development <gcc at gcc dot gnu dot org>
- Date: Tue, 12 May 2015 16:58:47 +0200
- Subject: Re: Missing barrier in outof_cfglayout
- Authentication-results: sourceware.org; auth=none
- References: <5550D693 dot 9000903 at gjlay dot de> <5550DFA5 dot 2000507 at redhat dot com> <5550E8E4 dot 50504 at gjlay dot de> <CABu31nPQH=QY+EgK0bdp1gB_jNrunwEt5XrHq5Jn-WOMn8bKiQ at mail dot gmail dot com>
Am 05/11/2015 um 10:43 PM schrieb Steven Bosscher:
On Mon, May 11, 2015 at 7:37 PM, Georg-Johann Lay wrote:
BTW, what's the policy about unconditional jumps at that time? There are
plenty of unconditional jumps around and all are legitimate; just this one
generated by cse1 is wrong?
If you're in cfglayout mode, then there should be no unconditional
jumps to labels. The only JUMP_INSNs should be unconditional,
computed, or return jumps.
If you do have unconditional jumps at this stage, something is seriously broken.
Ah, yes. The ICE is actually in verify_flow_info: "wrong number of branch
edges after unconditional jump in bb 4".
It starts with an almost trivial jump table:
(jump_insn 82 81 83 19 (parallel [
(set (pc)
(reg/f:SI 60))
(use (label_ref 83))
])
(nil)
-> 83)
;; succ: 20 [50.0%]
;; 31 [50.0%]
;; Insn is not within a basic block
(code_label 83 82 84 15 "" [3 uses])
;; Insn is not within a basic block
(jump_table_data 84 83 85 (addr_vec:SI [
(label_ref:SI 130)
(label_ref:SI 86)
(label_ref:SI 130)
(label_ref:SI 130)
]))
At .cse1, cse.c:cse_insn executes
/* We don't normally have an insn matching (set (pc) (pc)), so
check for this separately here. We will delete such an
insn below.
For other cases such as a table jump or conditional jump
where we know the ultimate target, go ahead and replace the
operand. While that may not make a valid insn, we will
reemit the jump below (and also insert any necessary
barriers). */
if (n_sets == 1 && dest == pc_rtx
&& (trial == pc_rtx
|| (GET_CODE (trial) == LABEL_REF
&& ! condjump_p (insn))))
{
/* Don't substitute non-local labels, this confuses CFG. */
if (GET_CODE (trial) == LABEL_REF
&& LABEL_REF_NONLOCAL_P (trial))
continue;
SET_SRC (sets[i].rtl) = trial;
cse_jumps_altered = true;
break;
}
on the jump insn and with trial = (label_ref 83).
The code pointed out by Jeff then replaces the original jump insn by
(jump_insn 139 81 82 16 (set (pc)
(label_ref 83)) bug.c:33 -1
(nil))
That's obviously nonsense as it jumps to the jump_table_data!
Johann