Jakub Jelinek <ja...@redhat.com> writes: > Hi! > > The following testcase used to be miscompiled by RTL jump threading > on s390x-linux with -march=zEC12 at -O2 before r269302 which made it latent. > The problem is we had: > (jump_insn 26 25 87 4 (parallel [ > (set (pc) > (if_then_else (eq (reg/v:DI 5 %r5 [orig:74 e ] [74]) > (const_int 1 [0x1])) > (label_ref 43) > (pc))) > (clobber (reg:CC 33 %cc)) > ]) "rh1686696.c":16:7 1263 {*cmp_and_br_signed_di} > (int_list:REG_BR_PROB 118111604 (nil)) > -> 43) > as the sole non-note non-code_label insn in basic block 4, and > (jump_insn 68 67 134 12 (parallel [ > (set (pc) > (if_then_else (ne (reg/v:DI 5 %r5 [orig:74 e ] [74]) > (const_int 1 [0x1])) > (label_ref:DI 23) > (pc))) > (set (reg/v:DI 5 %r5 [orig:74 e ] [74]) > (plus:DI (reg/v:DI 5 %r5 [orig:74 e ] [74]) > (const_int -1 [0xffffffffffffffff]))) > (clobber (scratch:DI)) > (clobber (reg:CC 33 %cc)) > ]) "rh1686696.c":13:3 1922 {doloop_di} > (int_list:REG_BR_PROB 904381916 (nil)) > -> 23) > as the sole non-note non-code_label insn in basic block 12, the doloop > conditional jump branching to the bb with the above jump_insn 26. > thread_jump sees one condition being %r5 == 1 and the other %r5 != 1, > performs the cselib assisted checks if the b sequence is really a noop > (but that starts with the original complete bb as a base and only does > nonequal processing in the e->src bb) and decided to change insn 68 > to jump after the jump_insn 26 because the comparison of %r5 against 1 > has been done already. > > It didn't take into account that %r5 has been modified in the doloop_di > insn though, so the conditions are comparing different values. > > I have thought about different approaches, below is the simplest one, > just punt if modified_in_p. Another possibility would be to handle the > BB_END (e->src) insn in the second rather than first loop and do the > nonequal handling in there, but I couldn't figure out what kind of insns > it would handle better than this more simple approach. It wouldn't handle > hypothetical condjump instruction which compares one register and modifies > another one, as it would add that register into nonequal and unless that > register has been unconditionally set to something else, would keep it > in nonequal and bail out.
Yeah. Looks like we'd have to do something overly complicated to separate the sets for the final EXECUTE_IF_SET_IN_REG_SET, and at that point it's equivalent to the simple way. > Bootstrapped/regtested on {x86_64,i686}-linux (where it didn't check much > because those targets don't have doloops) and on r269253 trunk (i.e. before > the r269302 change) on {powerpc64le,s390x}-linux (which both have doloop > insns). Ok for trunk? > > 2019-03-09 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/89634 > * cfgcleanup.c (thread_jump): Punt if registers mentioned in cond1 > are modified in BB_END (e->src) instruction. > > * gcc.c-torture/execute/pr89634.c: New test. OK, thanks. Richard