optimization/10024 [3.3 regression] [HP-PA] inline optimization ICE
Zack Weinberg
zack@codesourcery.com
Wed Mar 26 18:36:00 GMT 2003
The following reply was made to PR optimization/10024; it has been noted by GNATS.
From: Zack Weinberg <zack@codesourcery.com>
To: Cc: gcc-gnats@gcc.gnu.org, tausq@debian.org, gcc-bugs@gcc.gnu.org
Subject: Re: optimization/10024 [3.3 regression] [HP-PA] inline optimization
ICE
Date: Wed, 26 Mar 2003 10:24:50 -0800
I was able to reproduce this bug with an x86->HPPA cross compiler.
In 3.3, force_nonfallthru_and_redirect is called thus:
Breakpoint 4, force_nonfallthru_and_redirect (e=0x83896b0, target=0x8389110)
at ../../gcc/cfgrtl.c:936
936 basic_block jump_block, new_bb = NULL, src = e->src;
(gdb) p *e
$3 = {pred_next = 0x8389408, succ_next = 0x0, src = 0x8388f80,
dest = 0x8389110, insns = 0x0, aux = 0x0, flags = 1, probability = 10000,
count = 0}
Note that e->dest == target. These are the basic blocks involved:
;; Basic block 13, loop depth 0, count 0
;; Predecessors: 12 [100.0%] (fallthru) 7 [100.0%] (fallthru) 4 [100.0%] (fallthru)
;; Registers live at start: 2 [%r2] 20 [%r20] 30 [%r30]
(code_label 159 266 236 13 13 "" [0 uses])
(note 236 159 162 13 [bb 13] NOTE_INSN_BASIC_BLOCK)
(note 162 236 180 13 NOTE_INSN_DELETED)
(jump_insn:TI 180 162 142 13 0x40331688 (parallel [
(set (pc)
(if_then_else (ge (reg/v:SI 20 %r20 [123])
(const_int 0 [0x0]))
(label_ref 186)
(pc)))
(set (reg/v:SI 28 %r28 [104])
(reg/v:SI 20 %r20 [123]))
]) 232 {*pa.md:7406} (nil)
(expr_list:REG_DEAD (reg/v:SI 20 %r20 [123])
(expr_list:REG_BR_PROB (const_int 10000 [0x2710])
(nil))))
;; Registers live at end: 2 [%r2] 28 [%r28] 30 [%r30]
;; Successors: 14 [100.0%] (fallthru)
;; Basic block 14, loop depth 0, count 0
;; Predecessors: 13 [100.0%] (fallthru) 1 [100.0%] (fallthru)
;; Registers live at start: 2 [%r2] 28 [%r28] 30 [%r30]
(code_label 186 55 241 14 19 "" [1 uses])
(note 241 186 187 14 [bb 14] NOTE_INSN_BASIC_BLOCK)
(note 187 241 188 14 NOTE_INSN_DELETED)
(note 188 187 195 14 NOTE_INSN_DELETED)
(note 195 188 196 14 NOTE_INSN_DELETED)
(note 196 195 208 14 NOTE_INSN_DELETED)
(note 208 196 189 14 NOTE_INSN_FUNCTION_END)
(insn:TI 189 208 197 14 0x40331688 (set (reg/v:SI 19 %r19 [153])
(ashiftrt:SI (reg/v:SI 28 %r28 [104])
(const_int 16 [0x10]))) 189 {*pa.md:5429} (nil)
(nil))
(insn 197 189 198 14 0x4033165c (set (reg:SI 28 %r28 [158])
(zero_extract:SI (reg/v:SI 28 %r28 [104])
(const_int 1 [0x1])
(const_int 16 [0x10]))) 225 {extzv_32}
(insn_list:REG_DEP_ANTI 189 (nil))
(nil))
(insn:TI 198 197 214 14 0x4033165c (set (reg/v:SI 28 %r28 [151])
(plus:SI (reg/v:SI 19 %r19 [153])
(reg:SI 28 %r28 [158]))) 121 {addsi3}
(insn_list 197 (insn_list 189 (nil)))
(expr_list:REG_DEAD (reg/v:SI 19 %r19 [153])
(nil)))
(insn 214 198 269 14 0x40331528 (use (reg/i:SI 28 %r28)) -1
(insn_list:REG_DEP_ANTI 189
(insn_list:REG_DEP_ANTI 197 (insn_list 198 (nil))))
(nil))
(note 269 214 270 14 NOTE_INSN_EPILOGUE_BEG)
(jump_insn:TI 270 269 271 14 (nil) (parallel [
(return)
(use (reg:SI 2 %r2))
(const_int 0 [0x0])
]) 197 {return}
(insn_list:REG_DEP_ANTI 214 (insn_list 189 (insn_list 198 (nil))))
(expr_list:REG_DEAD (reg:SI 2 %r2)
(nil)))
;; Registers live at end: 28 [%r28] 30 [%r30]
;; Successors: EXIT [100.0%]
The crash occurs
note = find_reg_note (e->src->end, REG_BR_PROB, NULL_RTX);
if (note)
{
int prob = INTVAL (XEXP (note, 0));
b->probability = prob; /* here */
because make_edge returned NULL, which is what it is documented to do
when the edge it is asked to create already exists. I am dubious
about this interface - the caller presumably wants to get its hands on
the new edge, so wouldn't it make sense to return the already-existent
one? But that's too invasive a change for 3.3.
The minimal fix for this bug is to notice when "e" is the edge we
want, and use it instead of calling make_edge. This solves the crash,
and appears to generate correct code (my ability to read HPPA assembly
language is limited). It will not fix a more general bug where the
edge from e->src to target already exists, but is not e. I don't know
if that can happen.
In 3.4 something different is happening -- we get a verify_flow_info
failure, and this code path is never taken. I will continue looking.
I'd appreciate comments on the appended patch for 3.3.
zw
* cfgrtl.c (force_nonfallthru_and_redirect): If e is the edge
we want, use it.
===================================================================
Index: cfgrtl.c
--- cfgrtl.c 25 Mar 2003 20:31:42 -0000 1.61.2.4
+++ cfgrtl.c 26 Mar 2003 18:23:55 -0000
@@ -946,7 +946,11 @@ force_nonfallthru_and_redirect (e, targe
&& JUMP_LABEL (e->src->end) == e->dest->head)
{
rtx note;
- edge b = make_edge (e->src, target, 0);
+ edge b;
+ if (e->dest == target)
+ b = e;
+ else
+ b = make_edge (e->src, target, 0);
if (!redirect_jump (e->src->end, block_label (target), 0))
abort ();
More information about the Gcc-prs
mailing list