[PATCH] D68408: [InstCombine] Unfold `sub %x, %y` -> `add (sub 0, %y), %x` IFF `%y` can be freely negated

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 3 10:30:23 PDT 2019


lebedev.ri created this revision.
lebedev.ri added reviewers: spatel, nikic, efriedma.
lebedev.ri added a project: LLVM.
Herald added a subscriber: hiraditya.
lebedev.ri edited the summary of this revision.

As we have discussed previously (e.g. in D63992 <https://reviews.llvm.org/D63992> / D64090 <https://reviews.llvm.org/D64090> / PR42457 <https://bugs.llvm.org/show_bug.cgi?id=42457>), `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 PR42412 <https://bugs.llvm.org/show_bug.cgi?id=42412> / PR42389 <https://bugs.llvm.org/show_bug.cgi?id=42389>.

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?

This does have some potential to expose missing folds and cause endless combine loops.

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,
https://rise4fun.com/Alive/58xqwe
We should make use of this infrastructure to muster through in the opposite direction:
if `isFreeToNegate()` says that the `neg` can be sinked, we should sink it.

(The third part of the coin is that we may want to do the same for inversion (`xor %x, -1`).)

Thoughts?


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68408

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
  llvm/lib/Transforms/InstCombine/InstCombineInternal.h
  llvm/test/Transforms/InstCombine/sub-of-negatible.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68408.223048.patch
Type: text/x-patch
Size: 6667 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191003/3e02a9cf/attachment.bin>


More information about the llvm-commits mailing list