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 theor
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.