As we have discussed previously (e.g. in D63992 / D64090 / [[ https://bugs.llvm.org/show_bug.cgi?id=42457 | PR42457 ]]), `sub` instruction
can almost be considered non-canonical. While we do convert `sub %x, C` -> `add %x, -C`,
we sparsely do that for non-constants. But we should.
Here, i propose to explode `sub %x, %y` into `add (sub 0, %y), %x` IFF we *know* that `neg` can be sinked into the `%y`
My main motivation here is the `@t7`, which is from [[ https://bugs.llvm.org/show_bug.cgi?id=42412 | PR42412 ]] / [[ https://bugs.llvm.org/show_bug.cgi?id=42389 | PR42389 ]].
We know that `neg` is free if:
* We are negating an integral constant - https://rise4fun.com/Alive/6ploz
* The instruction in question has no users other than the negation itself. The rest of reasoning is recursive.
* It's a `select` - both hands must be negatible - https://rise4fun.com/Alive/MYge
* It's a `shl` - first operand must be negatible - https://rise4fun.com/Alive/7kA
* It's a `sub` - first operand must be negatible - https://rise4fun.com/Alive/ati7
* It's a `add` - both operands must be negatible - https://rise4fun.com/Alive/ou7
* It's a `mul` - either one of operands must be negatible - https://rise4fun.com/Alive/4tR
* (FIXME: there are likely more cases?)
Normally, InstCombine's worklist would cause the `add (sub 0, %y), %x` to be revisited first,
which would immediately get folded back into `sub %x, %y`, and we'd loop endlessly.
We want the `sub 0, %y` to be revisited first, so we have to manually mess with worklist.
This *is* unusual. Is this too ugly to live?
There's also a second part to this coin - while we currently mindlessly hoist `neg` if we can,
as it can be seen in `@dont_touch_negation_itself`'s case - there should not be a `neg` there,
We should make use of this infrastructure to muster `neg` in the opposite direction:
if `isFreeToNegate()` says that the `neg` can be sinked, we should sink it.
This does have some potential to expose missing folds and cause endless combine loops.
(The third part of the coin is that we may want to do the same for inversion (`xor %x, -1`).)