> The problem is in that r0-6313 change, which made count_reg_usage not
> count uses of the pseudo which the containing SET sets. That is needed
> so we can delete those instructions as trivially dead if they are really
> dead, but has the following problem. After fwprop proper we have:
> (insn 7 2 8 2 (set (reg/v:DI 101 [ g ])
> (const_int -1 [0xffffffffffffffff])) "pr119594.c":8:10 95
> {*movdi_internal} (nil))
> ...
> (insn 26 24 27 7 (set (reg:DI 104 [ g ])
> (zero_extend:DI (subreg:SI (reg/v:DI 101 [ g ]) 0)))
> "pr119594.c":11:8 175 {*zero_extendsidi2} (expr_list:REG_EQUAL (const_int
> 4294967295 [0xffffffff])
> (expr_list:REG_DEAD (reg/v:DI 101 [ g ])
> (nil))))
> (insn 27 26 28 7 (set (reg/v:DI 101 [ g ])
> (zero_extend:DI (subreg:SI (reg/v:DI 101 [ g ]) 0)))
> "pr119594.c":11:8 175 {*zero_extendsidi2} (expr_list:REG_EQUAL (const_int
> 4294967295 [0xffffffff])
> (expr_list:REG_UNUSED (reg/v:DI 101 [ g ])
> (nil))))
> and nothing else uses or sets the 101 and 104 pseudos. The subpass doesn't
> look at REG_UNUSED or REG_DEAD notes (correctly, as they aren't guaranteed
> to be accurate). The last change in the IL was forward propagation of
> (reg:DI 104 [ g ]) value into the following insn.
> Now, count_reg_usage doesn't count anything on insn 7, the SET_DEST is a
> reg, so we don't count that and SET_SRC doesn't contain any regs.
> On insn 26 it counts one usage of pseudo 101 (so counts[101] = 1) and
> on insn 27 since r0-6313 doesn't count anything as that insn sets
> pseudo 101 to something that uses it, it isn't a side-effect instruction
> and can't throw.
>
> Now, after counting reg usages the subpass walks the IL from end to start,
> sees insn 27, counts[101] is non-zero, so insn_live_p is true, nothing is
> deleted. Then sees insn 26, counts[104] is zero, insn_live_p is false,
> we delete the insn and decrease associated counts, in this case counts[101]
> becomes zero. And finally later we process insn 7, counts[101] is now zero,
> insn_live_p is false, we delete the insn (and decrease associated counts,
> which aren't any).
> Except that this resulted in insn 27 staying in the IL but using a REG
> which is no longer set (and worse, having a REG_EQUAL note of something we
> need later in the same bb, so we then assume pseudo 101 contains 0xffffffff,
> which it no longer does.
>
> Now, if insn 26 was after insn 27, this would work just fine, we'd first
> delete that and then insn 27 and then insn 7, which is why most of the time
> it happens to work fine.
I guess the question is: how much do we pessimize if we tweak r0-6313 change?
For example, we could say that a use of REG in the SET_SRC does not count if
REG is also set in the SET_DEST *only* if there is no previous use of REG:
case REG:
if (x == dest)
{
if (incr > 0 && counts[REGNO (x)] != 0)
counts[REGNO (x)] += incr;
}
else
counts[REGNO (x)] += incr;
return;
IIUC this would both fix the bug and preserve the deletion if insn 26 and 27
are swapped.
--
Eric Botcazou