commit | 32d24a32499cde9bc29007725db22de076d5b0e0 | [log] [tgz] |
---|---|---|

author | Roman Lebedev <lebedev.ri@gmail.com> | Sun Oct 20 19:38:50 2019 +0000 |

committer | Roman Lebedev <lebedev.ri@gmail.com> | Sun Oct 20 19:38:50 2019 +0000 |

tree | e976d3b28e4265306e534af305acacafb57885c4 | |

parent | 7bd6e166d9c76d62f76e801f9b55a84de03eb733 [diff] |

[InstCombine] Shift amount reassociation in shifty sign bit test (PR43595) Summary: This problem consists of several parts: * Basic sign bit extraction - `trunc? (?shr %x, (bitwidth(x)-1))`. This is trivial, and easy to do, we have a fold for it. * Shift amount reassociation - if we have two identical shifts, and we can simplify-add their shift amounts together, then we likely can just perform them as a single shift. But this is finicky, has one-use restrictions, and shift opcodes must be identical. But there is a super-pattern where both of these work together. to produce sign bit test from two shifts + comparison. We do indeed already handle this in most cases. But since we get that fold transitively, it has one-use restrictions. And what's worse, in this case the right-shifts aren't required to be identical, and we can't handle that transitively: If the total shift amount is bitwidth-1, only a sign bit will remain in the output value. But if we look at this from the perspective of two shifts, we can't fold - we can't possibly know what bit pattern we'd produce via two shifts, it will be *some* kind of a mask produced from original sign bit, but we just can't tell it's shape: https://rise4fun.com/Alive/cM0 https://rise4fun.com/Alive/9IN But it will *only* contain sign bit and zeros. So from the perspective of sign bit test, we're good: https://rise4fun.com/Alive/FRz https://rise4fun.com/Alive/qBU Superb! So the simplest solution is to extend `reassociateShiftAmtsOfTwoSameDirectionShifts()` to also have a sudo-analysis mode that will ignore extra-uses, and will only check whether a) those are two right shifts and b) they end up with bitwidth(x)-1 shift amount and return either the original value that we sign-checking, or null. This does not have any functionality change for the existing `reassociateShiftAmtsOfTwoSameDirectionShifts()`. All that being said, as disscussed in the review, this yet again increases usage of instsimplify in instcombine as utility. Some day that may need to be reevaluated. https://bugs.llvm.org/show_bug.cgi?id=43595 Reviewers: spatel, efriedma, vsk Reviewed By: spatel Subscribers: xbolva00, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D68930 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375371 91177308-0d34-0410-b5e6-96231b3b80d8

- lib/Transforms/InstCombine/InstCombineCompares.cpp[diff]
- lib/Transforms/InstCombine/InstCombineInternal.h[diff]
- lib/Transforms/InstCombine/InstCombineShifts.cpp[diff]
- test/Transforms/InstCombine/sign-bit-test-via-right-shifting-all-other-bits.ll[diff]

4 files changed

tree: e976d3b28e4265306e534af305acacafb57885c4