> 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