Open Quuxplusone opened 4 years ago
I track down reason and it was because InstCombine::visitGetElementPtrInst try to swap index operands of geps when it can exhibit more opportunities to LICM:
/* at InstructionCombining.cpp */
...
// Try to reassociate loop invariant GEP chains to enable LICM.
if (LI && Src->getNumOperands() == 2 && GEP.getNumOperands() == 2 &&
Src->hasOneUse()) {
...
ptr3's gep has a constant index (-1), so InstCombine chose to swap it with ptr2's index (%phi.ext) to enable code motion of the updated ptr2.
Here are a few solutions that I have:
(1) do this transformation when the two indices are known to have the same sign or either of those is zero. For example, if ptr3's index is 1 instead of -1, this transformation is allowed. (2) drop inbound flags when doing the transformation.
If %arg is 1, ptr3 in the source is
gep inb (gep inb ptr, 1), -1
whereas ptr3 in the target isgep inb (gep inb ptr, -1), 1
. This is incorrect because ptr3 in the tgt may be poison whereas ptr3 in the source isn't.