[RFC] Add or disjoint flag

Background

InstCombine canonicalizes add to or if every bit is known to be zero in at least one of the operands. In that case there can be no carry out of any bit so its safe to treat it as an or.

This transform isn’t always beneficial. For example, it can interfere with a backend’s ability to fold arithmetic into a load/store address.

A backend can try to reverse this transform, but it isn’t always successful. Particularly in unrolled loops when the unrolled induction variable is know to be a multiple of 4 or 8. Adding a small constant to it becomes an or.

SCEV knows how to reverse this transform so if LSR makes changes to the loop, the or will turn back to add when it gets rewritten. But of course LSR doesn’t touch all loops.

Proposal

The proposal is to add new disjoint flag to or, with the following semantics:

If the disjoint flag is set, and the or has a one in the same bit in both arguments, the result is poison.

Passes that convert add to or would add this flag, which would enable conversion back to add to be more reliable.

Patches

Initial patch to add the flag to IR [IR] Add disjoint flag for Or instructions. by topperc · Pull Request #72583 · llvm/llvm-project · GitHub Patches to set the flag and make use of it will follow.

5 Likes

This makes a lot of sense to me, and this seems very overdue - thank you for driving this. One challenge of these bits (just as with nuw etc) is maintaining them correctly, but it seems clearly worth the cost and can surely improve codegen compile time.