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
disjointflag is set, and theorhas 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.