This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] Recognize that and(x, add (x, -1)) clears the low bit
ClosedPublic

Authored by reames on Nov 3 2015, 7:02 PM.

Details

Summary

This is a cleaned up version of a patch by John Regehr with permission. Originally found via the souper tool.

If we add an odd number to x, then bitwise-and the result with x, we know that the low bit of the result must be zero. Either it was zero in x originally, or the add cleared it in the temporary value. As a result, one of the two values anded together must have the bit cleared.

Diff Detail

Repository
rL LLVM

Event Timeline

reames updated this revision to Diff 39148.Nov 3 2015, 7:02 PM
reames retitled this revision from to [ValueTracking] Recognize that and(x, add (x, -1)) clears the low bit.
reames updated this object.
reames added reviewers: regehr, sanjoy, majnemer.
reames added a subscriber: llvm-commits.
sanjoy accepted this revision.Nov 6 2015, 12:10 PM
sanjoy edited edge metadata.

Minor optional to fix nit inline

lib/Analysis/ValueTracking.cpp
1092 ↗(On Diff #39148)

This is minor:

I think (but perhaps @majnemer can confirm this) instcombine canonicalizes operands (for commutative operations) so that the LHS is more complex than the RHS, so maybe there is not much value in checking for both "x & (x - 1)" and "(x - 1) & x" -- instcombine will transform the former to the latter.

This revision is now accepted and ready to land.Nov 6 2015, 12:10 PM
reames added inline comments.Nov 10 2015, 10:04 AM
lib/Analysis/ValueTracking.cpp
1092 ↗(On Diff #39148)

I don't think it will in this case. I believe the definition of complexity is on the type of the operand (constant, non-constant, etc..), not the form of the operand.

This revision was automatically updated to reflect the committed changes.