From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28858 invoked by alias); 26 Mar 2003 18:36:03 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 28835 invoked by uid 71); 26 Mar 2003 18:36:01 -0000 Date: Wed, 26 Mar 2003 18:45:00 -0000 Message-ID: <20030326183601.28833.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Zack Weinberg Subject: Re: optimization/10024 [3.3 regression] [HP-PA] inline optimization ICE Reply-To: Zack Weinberg X-SW-Source: 2003-03/txt/msg01824.txt.bz2 List-Id: The following reply was made to PR optimization/10024; it has been noted by GNATS. From: Zack Weinberg To: gcc-patches@gcc.gnu.org Cc: gcc-gnats@gcc.gnu.org, tausq@debian.org Subject: Re: optimization/10024 [3.3 regression] [HP-PA] inline optimization ICE Date: Wed, 26 Mar 2003 10:27:54 -0800 [apologies if you get this twice, I mangled the destination addresses the first time] 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 ();