This patch builds on http://reviews.llvm.org/D4490, which added the infrastructure to compute known bits using invariants. That original patch added only a few patterns (to catch common cases related to determining pointer alignment); this patch adds several other patterns for simple cases.
The initial patch contained that, for invariant(v & b = a), bits in the mask that are known to be one, we can propagate known bits from the a to v. It also had a known-bits transfer for invariant(a = b). This patch adds:
invariant(~(v & b) = a) : For those bits in the mask that are known to be one, we can propagate inverted known bits from the a to v.
invariant(v | b = a) : For those bits in b that are known to be zero, we can propagate known bits from the a to v.
invariant(~(v | b) = a): For those bits in b that are known to be zero, we can propagate inverted known bits from the a to v.
invariant(v ^ b = a) : For those bits in b that are known to be zero, we can propagate known bits from the a to v. For those bits in b that are known to be one, we can propagate inverted known bits from the a to v.
invariant(~(v ^ b) = a) : For those bits in b that are known to be zero, we can propagate inverted known bits from the a to v. For those bits in b that are known to be one, we can propagate known bits from the a to v.
invariant(v << c = a) : For those bits in a that are known, we can propagate them to known bits in v shifted to the right by c.
invariant(~(v << c) = a) : For those bits in a that are known, we can propagate them inverted to known bits in v shifted to the right by c.
invariant(v >> c = a) : For those bits in a that are known, we can propagate them to known bits in v shifted to the right by c.
invariant(~(v >> c) = a) : For those bits in a that are known, we can propagate them inverted to known bits in v shifted to the right by c.
invariant(v >=_s c) where c is non-negative: The sign bit of v is zero
invariant(v >_s c) where c is at least -1: The sign bit of v is zero
invariant(v <=_s c) where c is negative: The sign bit of v is one
invariant(v <_s c) where c is non-positive: The sign bit of v is one
invariant(v <=_u c): Transfer the known high zero bits
invariant(v <_u c): Transfer the known high zero bits (if c is know to be a power of 2, transfer one more)
A small addition to InstCombine was necessary for some of the test cases. The problem is that when InstCombine was simplifying and, or, etc. it would fail to check the 'do I know all of the bits' condition before checking less specific conditions and would not fully constant-fold the result. I'm not sure how to trigger this aside from using invariants, so I've just included the change here.