This is an archive of the discontinued LLVM Phabricator instance.

Compute known bits using invariants (addendum)
ClosedPublic

Authored by hfinkel on Jul 16 2014, 12:01 PM.

Details

Reviewers
chandlerc
hfinkel
Summary

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.

Diff Detail

Event Timeline

hfinkel updated this revision to Diff 11520.Jul 16 2014, 12:01 PM
hfinkel retitled this revision from to Compute known bits using invariants (addendum).
hfinkel updated this object.
hfinkel edited the test plan for this revision. (Show Details)
hfinkel added a reviewer: chandlerc.
hfinkel added a subscriber: Unknown Object (MLST).
hfinkel updated this revision to Diff 11699.Jul 20 2014, 11:59 AM

Renamed to llvm.assume.

hfinkel updated this revision to Diff 11934.Jul 27 2014, 11:26 PM

Rebased and updated for the AssumptionTracker.

hfinkel accepted this revision.Sep 7 2014, 1:34 PM
hfinkel added a reviewer: hfinkel.

(will close)

This revision is now accepted and ready to land.Sep 7 2014, 1:34 PM
hfinkel closed this revision.Sep 7 2014, 1:34 PM

r217343.