Jakub Jelinek <[email protected]> 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 <[email protected]>
>
> 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