* libcall problem during new unroller merge @ 2003-02-06 13:59 Zdenek Dvorak 2003-02-06 14:43 ` Jan Hubicka 0 siblings, 1 reply; 7+ messages in thread From: Zdenek Dvorak @ 2003-02-06 13:59 UTC (permalink / raw) To: gcc; +Cc: jh, rth Hello, during merging new loop unroller, I have encountered the following problem (masked on rtlopt branch by other pass): Consider loop in that strcmp is called; it is translated into rtl as (insn 542 541 543 (nil) (set (reg:SI 236) (mem/s/u:SI (plus:SI (reg:SI 235) (reg:SI 231)) [9 <variable>.name+0 S4 A32])) -1 (nil) (nil)) (insn 543 542 544 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 56 virtual-outgoing-args) (const_int 4 [0x4])) [0 S4 A32]) (reg:SI 236)) -1 (nil) (insn_list:REG_LIBCALL 547 (nil))) (insn 544 543 545 (nil) (set (reg:SI 237) (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32])) -1 (nil) (nil)) (insn 545 544 546 (nil) (set (mem/f:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32]) (reg:SI 237)) -1 (nil) (nil)) (call_insn/u 546 545 547 (nil) (set (reg:SI 0 eax) (call (mem:QI (symbol_ref:SI ("strcmp")) [0 S1 A8]) (const_int 8 [0x8]))) -1 (nil) (expr_list:REG_EH_REGION (const_int -1 [0xffffffff]) (nil)) (expr_list (use (mem:BLK (scratch) [0 A8])) (nil))) (insn 547 546 548 (nil) (set (reg:SI 238) (reg:SI 0 eax)) -1 (nil) (insn_list:REG_RETVAL 543 (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) (expr_list (symbol_ref:SI ("strcmp")) (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) (reg:SI 231)) [9 <variable>.name+0 S4 A32]) (nil))))) (nil)))) now first cse pass transforms insn 542 into (insn 542 541 543 71 0x402e1108 (set (reg:SI 236 [ <variable>.name ]) (mem/s/u:SI (plus:SI (reg:SI 235) (symbol_ref:SI ("processor_alias_table.2"))) [9 <variable>.name+0 S4 A32])) 38 {*movsi_1} (nil) (nil)) Reference in REG_EQUAL is not updated; set of reg. 231 disappears. Similarily, reg. 235 disappears in global copy propagation (in jump bypassing pass), being replaced by other register; again, reference in REG_EQUAL is not updated. REG_RETVAL note now refers only to non-existent registers, and unroller creates 4 consecutive clones of this block. Finally, second cse pass uses these notes to replace 3 of copies of insn 547 by (insn 1870 1869 1871 150 0x4016bfa4 (set (reg:SI 238) (reg:SI 238)) 38 {*movsi_1} (nil) (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) (expr_list (symbol_ref:SI ("strcmp")) (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) (reg/f:SI 231)) [9 <variable>.name+0 S4 A32]) (nil))))) (insn_list:REG_RETVAL 1866 (nil)))) causing misscompilation. In my opinion, the fact that REG_RETVAL note refers to completely bogus expression is wrong; but I am not sure where is the right place to fix it. Zdenek ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-06 13:59 libcall problem during new unroller merge Zdenek Dvorak @ 2003-02-06 14:43 ` Jan Hubicka 2003-02-06 14:57 ` Jan Hubicka 2003-02-07 15:06 ` Zdenek Dvorak 0 siblings, 2 replies; 7+ messages in thread From: Jan Hubicka @ 2003-02-06 14:43 UTC (permalink / raw) To: Zdenek Dvorak; +Cc: gcc, jh, rth > Hello, > > during merging new loop unroller, I have encountered the following > problem (masked on rtlopt branch by other pass): > > Consider loop in that strcmp is called; it is translated into rtl as > > (insn 542 541 543 (nil) (set (reg:SI 236) > (mem/s/u:SI (plus:SI (reg:SI 235) > (reg:SI 231)) [9 <variable>.name+0 S4 A32])) -1 (nil) > (nil)) > > (insn 543 542 544 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 56 virtual-outgoing-args) > (const_int 4 [0x4])) [0 S4 A32]) > (reg:SI 236)) -1 (nil) > (insn_list:REG_LIBCALL 547 (nil))) > > (insn 544 543 545 (nil) (set (reg:SI 237) > (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32])) -1 (nil) > (nil)) > > (insn 545 544 546 (nil) (set (mem/f:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32]) > (reg:SI 237)) -1 (nil) > (nil)) > > (call_insn/u 546 545 547 (nil) (set (reg:SI 0 eax) > (call (mem:QI (symbol_ref:SI ("strcmp")) [0 S1 A8]) > (const_int 8 [0x8]))) -1 (nil) > (expr_list:REG_EH_REGION (const_int -1 [0xffffffff]) > (nil)) > (expr_list (use (mem:BLK (scratch) [0 A8])) > (nil))) > > (insn 547 546 548 (nil) (set (reg:SI 238) > (reg:SI 0 eax)) -1 (nil) > (insn_list:REG_RETVAL 543 (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) > (expr_list (symbol_ref:SI ("strcmp")) > (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) > (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) > (reg:SI 231)) [9 <variable>.name+0 S4 A32]) > (nil))))) > (nil)))) > > now first cse pass transforms insn 542 into > > (insn 542 541 543 71 0x402e1108 (set (reg:SI 236 [ <variable>.name ]) > (mem/s/u:SI (plus:SI (reg:SI 235) > (symbol_ref:SI ("processor_alias_table.2"))) [9 <variable>.name+0 S4 A32])) 38 {*movsi_1} (nil) > (nil)) > > Reference in REG_EQUAL is not updated; set of reg. 231 disappears. > > Similarily, reg. 235 disappears in global copy propagation (in > jump bypassing pass), being replaced by other register; again, > reference in REG_EQUAL is not updated. I think jump bypassing is guilty here. In my vision of GCC, CSE should update REG_EQUAL note as well as it should behave equally to all occurences of given register, but independently on that no-one should kill the register 235 as long as it is used by some REG_EQUAL. How it is possible that copy propagation replaces the destination of insn? I wrote part of it and it was always meant to only update the sources, possibly making insn dead. Honza ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-06 14:43 ` Jan Hubicka @ 2003-02-06 14:57 ` Jan Hubicka 2003-02-07 15:06 ` Zdenek Dvorak 1 sibling, 0 replies; 7+ messages in thread From: Jan Hubicka @ 2003-02-06 14:57 UTC (permalink / raw) To: Jan Hubicka; +Cc: Zdenek Dvorak, gcc, rth, joern.rennecke Hmm, there seems to be something bogus in cprop pass. Comments says: if (newcnst && constprop_register (insn, x, newcnst, alter_jumps)) { /* If we find a case where we can't fix the retval REG_EQUAL notes match the new register, we either have to abandon this replacement or fix delete_trivially_dead_insns to preserve the setting insn, or make it delete the REG_EUAQL note, and fix up all passes that require the REG_EQUAL note there. */ if (!adjust_libcall_notes (x, newcnst, insn, libcall_sp)) abort (); However delete_trivially_dead_insns should preserve the insn. It is dealing with REG_EQUAL notes in count_reg_usage: case INSN: case JUMP_INSN: count_reg_usage (PATTERN (x), counts, NULL_RTX, incr); /* Things used in a REG_EQUAL note aren't dead since loop may try to use them. */ count_reg_usage (REG_NOTES (x), counts, NULL_RTX, incr); return; case EXPR_LIST: case INSN_LIST: if (REG_NOTE_KIND (x) == REG_EQUAL || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)) count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); return; default: break; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) So what is wrong here? Why the adjust_libcall_notes is needed at first place? Perhaps it is PRE who is killing the insn? Honza ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-06 14:43 ` Jan Hubicka 2003-02-06 14:57 ` Jan Hubicka @ 2003-02-07 15:06 ` Zdenek Dvorak 2003-02-07 15:40 ` Jan Hubicka 1 sibling, 1 reply; 7+ messages in thread From: Zdenek Dvorak @ 2003-02-07 15:06 UTC (permalink / raw) To: Jan Hubicka; +Cc: gcc, rth Hello, > > during merging new loop unroller, I have encountered the following > > problem (masked on rtlopt branch by other pass): > > > > Consider loop in that strcmp is called; it is translated into rtl as > > > > (insn 542 541 543 (nil) (set (reg:SI 236) > > (mem/s/u:SI (plus:SI (reg:SI 235) > > (reg:SI 231)) [9 <variable>.name+0 S4 A32])) -1 (nil) > > (nil)) > > > > (insn 543 542 544 (nil) (set (mem/f:SI (plus:SI (reg/f:SI 56 virtual-outgoing-args) > > (const_int 4 [0x4])) [0 S4 A32]) > > (reg:SI 236)) -1 (nil) > > (insn_list:REG_LIBCALL 547 (nil))) > > > > (insn 544 543 545 (nil) (set (reg:SI 237) > > (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32])) -1 (nil) > > (nil)) > > > > (insn 545 544 546 (nil) (set (mem/f:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32]) > > (reg:SI 237)) -1 (nil) > > (nil)) > > > > (call_insn/u 546 545 547 (nil) (set (reg:SI 0 eax) > > (call (mem:QI (symbol_ref:SI ("strcmp")) [0 S1 A8]) > > (const_int 8 [0x8]))) -1 (nil) > > (expr_list:REG_EH_REGION (const_int -1 [0xffffffff]) > > (nil)) > > (expr_list (use (mem:BLK (scratch) [0 A8])) > > (nil))) > > > > (insn 547 546 548 (nil) (set (reg:SI 238) > > (reg:SI 0 eax)) -1 (nil) > > (insn_list:REG_RETVAL 543 (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) > > (expr_list (symbol_ref:SI ("strcmp")) > > (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) > > (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) > > (reg:SI 231)) [9 <variable>.name+0 S4 A32]) > > (nil))))) > > (nil)))) one question to this -- what does the expr_list inside REG_EQUAL mean? From the documentation I've got feeling that there should be rtl expression of value of libcall; is this some way to express that this is call to function with those arguments that is not documented? Anyway, it makes delete_trivially_dead_insns wrong, as it does not find register usage in this REG_EQUAL note. Zdenek ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-07 15:06 ` Zdenek Dvorak @ 2003-02-07 15:40 ` Jan Hubicka 2003-02-07 21:14 ` Zdenek Dvorak 2003-02-09 6:19 ` Richard Henderson 0 siblings, 2 replies; 7+ messages in thread From: Jan Hubicka @ 2003-02-07 15:40 UTC (permalink / raw) To: Zdenek Dvorak; +Cc: Jan Hubicka, gcc, rth > Hello, > > > (insn 547 546 548 (nil) (set (reg:SI 238) > > > (reg:SI 0 eax)) -1 (nil) > > > (insn_list:REG_RETVAL 543 (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) > > > (expr_list (symbol_ref:SI ("strcmp")) > > > (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) > > > (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) > > > (reg:SI 231)) [9 <variable>.name+0 S4 A32]) > > > (nil))))) > > > (nil)))) > > one question to this -- what does the expr_list inside REG_EQUAL mean? It is just place holder - we don't have RTL construct to represent call with arguments, so we present it as linked list of expression. Function is first, arguments follows > >From the documentation I've got feeling that there should be rtl > expression of value of libcall; is this some way to express that this > is call to function with those arguments that is not documented? > Anyway, it makes delete_trivially_dead_insns wrong, as it does not > find register usage in this REG_EQUAL note. THis looks like the problem. Now I see, delte_trivially_dead_insns ignores body of expr_list. DOes this patch fix the problem? Index: cse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cse.c,v retrieving revision 1.253 diff -c -3 -p -r1.253 cse.c *** cse.c 28 Jan 2003 21:29:40 -0000 1.253 --- cse.c 7 Feb 2003 15:40:08 -0000 *************** count_reg_usage (x, counts, dest, incr) *** 7461,7466 **** --- 7461,7467 ---- int incr; { enum rtx_code code; + rtx note; const char *fmt; int i, j; *************** count_reg_usage (x, counts, dest, incr) *** 7518,7533 **** /* Things used in a REG_EQUAL note aren't dead since loop may try to use them. */ ! count_reg_usage (REG_NOTES (x), counts, NULL_RTX, incr); return; - case EXPR_LIST: case INSN_LIST: ! if (REG_NOTE_KIND (x) == REG_EQUAL ! || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)) ! count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr); ! count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr); ! return; default: break; --- 7519,7531 ---- /* Things used in a REG_EQUAL note aren't dead since loop may try to use them. */ ! note = find_reg_equal_equiv_note (x); ! if (note) ! count_reg_usage (XEXP (note, 0), counts, NULL_RTX, incr); return; case INSN_LIST: ! abort (); default: break; ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-07 15:40 ` Jan Hubicka @ 2003-02-07 21:14 ` Zdenek Dvorak 2003-02-09 6:19 ` Richard Henderson 1 sibling, 0 replies; 7+ messages in thread From: Zdenek Dvorak @ 2003-02-07 21:14 UTC (permalink / raw) To: Jan Hubicka; +Cc: gcc, rth Hello, > > > > (insn 547 546 548 (nil) (set (reg:SI 238) > > > > (reg:SI 0 eax)) -1 (nil) > > > > (insn_list:REG_RETVAL 543 (expr_list:REG_EQUAL (expr_list (use (mem:BLK (scratch) [0 A8])) > > > > (expr_list (symbol_ref:SI ("strcmp")) > > > > (expr_list (mem/f:SI (symbol_ref:SI ("ix86_cpu_string")) [9 ix86_cpu_string+0 S4 A32]) > > > > (expr_list (mem/s/u:SI (plus:SI (reg:SI 235) > > > > (reg:SI 231)) [9 <variable>.name+0 S4 A32]) > > > > (nil))))) > > > > (nil)))) > > > > one question to this -- what does the expr_list inside REG_EQUAL mean? > > It is just place holder - we don't have RTL construct to represent call > with arguments, so we present it as linked list of expression. Function > is first, arguments follows > > >From the documentation I've got feeling that there should be rtl > > expression of value of libcall; is this some way to express that this > > is call to function with those arguments that is not documented? > > Anyway, it makes delete_trivially_dead_insns wrong, as it does not > > find register usage in this REG_EQUAL note. > > THis looks like the problem. Now I see, delte_trivially_dead_insns > ignores body of expr_list. > DOes this patch fix the problem? yes; it seems that disappearance of both registers was caused by this bug. I will run the bootstrap again, hopefully it will pass now. Zdenek ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: libcall problem during new unroller merge 2003-02-07 15:40 ` Jan Hubicka 2003-02-07 21:14 ` Zdenek Dvorak @ 2003-02-09 6:19 ` Richard Henderson 1 sibling, 0 replies; 7+ messages in thread From: Richard Henderson @ 2003-02-09 6:19 UTC (permalink / raw) To: Jan Hubicka; +Cc: Zdenek Dvorak, gcc On Fri, Feb 07, 2003 at 04:40:36PM +0100, Jan Hubicka wrote: > THis looks like the problem. Now I see, delte_trivially_dead_insns > ignores body of expr_list. > DOes this patch fix the problem? The patch is ok. r~ ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-02-09 6:19 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-02-06 13:59 libcall problem during new unroller merge Zdenek Dvorak 2003-02-06 14:43 ` Jan Hubicka 2003-02-06 14:57 ` Jan Hubicka 2003-02-07 15:06 ` Zdenek Dvorak 2003-02-07 15:40 ` Jan Hubicka 2003-02-07 21:14 ` Zdenek Dvorak 2003-02-09 6:19 ` Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).