This is an archive of the discontinued LLVM Phabricator instance.

Re-enable "[IndVars] Canonicalize comparisons between non-negative values and indvars"
ClosedPublic

Authored by mkazantsev on Jul 6 2017, 11:18 PM.

Details

Summary

The patch was reverted due to a bug. The bug was that if the IV is the 2nd operand of the icmp
instruction, then the "Pred" variable gets swapped and differs from the instruction's predicate.
In this patch we use the original predicate to do the transformation.

Also added a test case that exercises this situation.

Diff Detail

Event Timeline

mkazantsev created this revision.Jul 6 2017, 11:18 PM

It works. I could approve but I will wait for 3rd person.

FYI, you may reopen D34979 for it.

anna accepted this revision.Jul 7 2017, 5:43 AM

LGTM.

lib/Transforms/Utils/SimplifyIndVar.cpp
268

Could you please add a comment here why you're using the OriginalPred.
It seems useful to state it.

Also,IIUC, doing this transform when Pred is swapped version of OriginalPred is error prone. We also need to check that IV is the second operand to avoid breaking canonicalization -- IV is always on the left.

This revision is now accepted and ready to land.Jul 7 2017, 5:43 AM
mkazantsev added inline comments.Jul 7 2017, 6:02 AM
lib/Transforms/Utils/SimplifyIndVar.cpp
268

That's what actually what the bug was. I used to use Pred here, which was wrong in the situation:

sgt 100, iv

We wanted to operate with "slt iv, 100" within the method, but the tricky thing is that the instruction remained unchanged, we only replace the Pred variable and not operate in terms of left and right operand, but use this thing:

const SCEV *S = SE->getSCEV(ICmp->getOperand(IVOperIdx));
const SCEV *X = SE->getSCEV(ICmp->getOperand(1 - IVOperIdx));

So in the described situation the actual instruction is "sgt 100, iv", but the Pred variable is "slt". What we want to have in the end is "ugt 100, iv", that's why we need the original pred (or alternatively swap Pred twice in this case).

I will add a comment on that.

mkazantsev updated this revision to Diff 105627.Jul 7 2017, 6:11 AM
mkazantsev marked an inline comment as done.

Added a comment explaining why we use OriginalPred.

anna added inline comments.Jul 7 2017, 6:16 AM
lib/Transforms/Utils/SimplifyIndVar.cpp
268

Thanks.
Actually, what I meant was even enabling this transform *correctly* using Pred is error prone (but won't be a bug). The reason is precisely what you mentioned... we swap the predicate but not the operands. So, we need to swap the operands back, but only if Pred is swapped version of OriginalPred *and* IV is on the right. As we can see depending on Pred is highly prone to errors :)
However, what you've done here is strictly correct, since we don't depend on knowing if Pred was changed in someway.

mkazantsev closed this revision.Jul 8 2017, 11:19 AM

Merged as 307477.