On 11/8/18 4:00 AM, Alexandre Oliva wrote:
> When in_a resolves to a register set in the prev_clobber insn, we may
> use the SET_SRC for the compare instead. However, when in_b so
> resolves, we proceed to use the reg with its earlier value. When both
> resolve to the same register and prev_clobber is an insn that modifies
> the register, this arrangement may cause the compare to match (when it
> shouldn't) and the elimination of the compare to incorrectly succeed.
>
> (set (reg 1) (plus (reg 1) (const_int N)))
> (set (reg 2) (reg 1))
> (set (reg flags) (compare (reg 1) (reg 2)))
>
> in_a: (reg 1) --> (plus (reg 1) (const_int N))
> in_b: (reg 2) -> (reg 1) -/> oops
>
> (parallel [
> (set (reg flags) (compare (plus (reg 1) (const_int N))
> (reg 1))) ;; should be (plus...)
> (set (reg 1) (plus (reg 1) (const_int N)))])
> (set (reg 2) (reg 1))
>
> This patch arranges for in_b to also undergo SET_SRC substitution
> when appropriate, with a shortcut for when in_a and in_b are the same
> rtx.
>
> Bootstrapped, now regression-testing, on x86_64- and i686-linux-gnu. Ok
> to install if it passes?
>
>
> for gcc/ChangeLog
>
> PR rtl-optimization/86438
> * compare-elim.c (try_eliminate_compare): Use SET_SRC instead
> of in_b for the compare if in_b is SET_DEST.
>
> for gcc/testsuite/ChangeLog
>
> PR rtl-optimization/86438
> * gcc.dg/torture/pr86438.c: New.
OK.
jeff