On Fri, Apr 28, 2017 at 12:32:47PM -0600, Jeff Law wrote: > On 04/26/2017 05:25 AM, Jakub Jelinek wrote: > > On Tue, Apr 25, 2017 at 09:31:00PM +0200, Jakub Jelinek wrote: > > > This patch let us search for x's setter earlier in the bb. > > > During testing I found that modified_in_p/modified_in_between_p don't > > > actually take into account calls that could change MEMs, so the patch > > > handles that too. > > > > Or shall we just: > > --- gcc/alias.c 2017-04-25 15:51:31.072923325 +0200 > > +++ gcc/alias.c 2017-04-26 13:23:55.595048464 +0200 > > @@ -3221,6 +3221,8 @@ memory_modified_in_insn_p (const_rtx mem > > { > > if (!INSN_P (insn)) > > return false; > > + if (CALL_P (insn)) > > + return true; > > memory_modified = false; > > note_stores (PATTERN (insn), memory_modified_1, CONST_CAST_RTX(mem)); > > return memory_modified; > > > > instead of the call_crossed hacks? Then modified_between_p and > > modified_in_p would return true for !MEM_READONLY_P MEMs crossing a call. > This seems like a good idea as well. I'm a bit surprised we're not handling > it this way already. If you want to go w ith this and simplify the patch > for 80491, that's fine too.
Ok, I went with the above patch plus the following simplified version of the ifcvt.c change. I've additionally bootstrapped just the alias.c change compared to vanilla trunk and the only code generation differences (without the ifcvt.c patch) were in alias.o from cc1* objects (because it was patched), and all stage3 shared libraries were also identical, which means it is unlikely it hurts a lot. 2017-04-29 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/80491 * ifcvt.c (noce_process_if_block): When looking for x setter with missing else_bb, don't check only the insn right before cond_earliest, but look for the last insn that x is modified in within the same bb. --- gcc/ifcvt.c.jj 2017-04-04 19:51:33.000000000 +0200 +++ gcc/ifcvt.c 2017-04-24 16:01:09.784787699 +0200 @@ -3440,7 +3440,14 @@ noce_process_if_block (struct noce_if_in } else { - insn_b = prev_nonnote_nondebug_insn (if_info->cond_earliest); + insn_b = if_info->cond_earliest; + do + insn_b = prev_nonnote_nondebug_insn (insn_b); + while (insn_b + && (BLOCK_FOR_INSN (insn_b) + == BLOCK_FOR_INSN (if_info->cond_earliest)) + && !modified_in_p (x, insn_b)); + /* We're going to be moving the evaluation of B down from above COND_EARLIEST to JUMP. Make sure the relevant data is still intact. */ Jakub