This is an archive of the discontinued LLVM Phabricator instance.

isInductionPHI - Add some safety checks
Needs ReviewPublic

Authored by syzaara on Jul 13 2022, 8:46 AM.

Details

Reviewers
nickdesaulniers
Meinersbur
fhahn
MaskRay
Group Reviewers
Restricted Project
Summary

This adds some safety checks into isInductionPHI so that users calling isInductionPHI do not need to do their own checks before calling the function.

Diff Detail

Event Timeline

syzaara created this revision.Jul 13 2022, 8:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 13 2022, 8:46 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
syzaara requested review of this revision.Jul 13 2022, 8:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 13 2022, 8:46 AM
nickdesaulniers accepted this revision.Jul 13 2022, 8:50 AM

Untested, but LGTM; thanks for this cleanup!

This revision is now accepted and ready to land.Jul 13 2022, 8:50 AM
syzaara added a comment.EditedJul 13 2022, 9:08 AM

Untested, but LGTM; thanks for this cleanup!

I'm not quite sure how to test this. I could test it through my use case in rewriteLoopExitValues for which I have tests already comitted (so it's more of an NFC). Or, it could be through some unit tests for isInductionPHI itself, I see tests in llvm/unittests/Analysis/IVDescriptorsTest.cpp. But these checks seem too trivial to add unit tests for. Is it okay to commit this without further testing?

fhahn requested changes to this revision.Jul 13 2022, 9:29 AM
fhahn added a subscriber: fhahn.
fhahn added inline comments.
llvm/lib/Analysis/IVDescriptors.cpp
1509

This should never be called with Phi being null.

1537

This is overly restrictive, whether the loop has a pre-header or not shouldn't impact whether a phi is an induction or now.

This revision now requires changes to proceed.Jul 13 2022, 9:29 AM
syzaara added inline comments.Jul 13 2022, 9:47 AM
llvm/lib/Analysis/IVDescriptors.cpp
1537

On the line below, we query for AR->getLoop()->getLoopPreheader(). If it turns out that this is null, we will see a crash. I thought adding this would be safer rather than restrictive.

llvm/lib/Analysis/IVDescriptors.cpp
1537

maybe Phi::getIncomingValueForBlock should return nullptr if passed nullptr?

syzaara marked an inline comment as not done.Jul 13 2022, 10:36 AM
syzaara added inline comments.
llvm/lib/Analysis/IVDescriptors.cpp
1537

Yes, the other option is it move this check into Phi::getIncomingValueForBlock. @fhahn would that be more preferable?

llvm/lib/Analysis/IVDescriptors.cpp
1509

Sounds like a good case for Phi being a & (and additional const) rather than a non-const ptr.

nikic added a subscriber: nikic.Jul 13 2022, 12:16 PM
nikic added inline comments.
llvm/lib/Analysis/IVDescriptors.cpp
1537

It would be possible to relax this to getLoopPredecessor(). Without a loop predecessor we would have to guard against multiple starting values, which is probably not worthwhile?

fhahn added inline comments.Jul 13 2022, 12:37 PM
llvm/lib/Analysis/IVDescriptors.cpp
1537

If it turns out that this is null, we will see a crash

Oh yes, this also seems overly restrictive :/

The main thing we need an IR value to use as start value.

Given that we already require a single latch, checking that all non-latch incoming values are the same should be fairly straight-forward :)

Or maybe it is fine to pick any one of the non-latch incoming values as start value. We require the phi to form an AddRec, so it should have a single start value. Even if the incoming values are different IR values, they should evaluate to the same concrete value.

syzaara marked an inline comment as not done.Jul 13 2022, 1:07 PM
syzaara added inline comments.
llvm/lib/Analysis/IVDescriptors.cpp
1537

Ok, I can try picking any of the non-latch incoming values and test that out. Another option is what isFPInductionPHI does:

// The loop may have multiple entrances or multiple exits; we can analyze                 
// this phi if it has a unique entry value and a unique backedge value.                   
if (Phi->getNumIncomingValues() != 2)                                                     
  return false;                                                                           
Value *BEValue = nullptr, *StartValue = nullptr;
if (TheLoop->contains(Phi->getIncomingBlock(0))) {                                        
  BEValue = Phi->getIncomingValue(0);                                                     
  StartValue = Phi->getIncomingValue(1);                                                  
} else {
  assert(TheLoop->contains(Phi->getIncomingBlock(1)) &&
         "Unexpected Phi node in the loop");
  BEValue = Phi->getIncomingValue(1);                                                     
  StartValue = Phi->getIncomingValue(0);
}
fhahn added inline comments.Jul 13 2022, 9:39 PM
llvm/lib/Analysis/IVDescriptors.cpp
1537

That seems like a good first step. IMO it would also make sense for them both to share the same logic to get the start value.

syzaara added inline comments.Jul 18 2022, 7:01 AM
llvm/lib/Analysis/IVDescriptors.cpp
1509

This would require many changes to all the places we call isInductionPHI from. Can we add the null check for now, and create a separate PR for this change? @fhahn

MaskRay requested changes to this revision.Jul 18 2022, 10:33 AM
MaskRay added a subscriber: MaskRay.
MaskRay added inline comments.
llvm/lib/Analysis/IVDescriptors.cpp
1509

No. Many APIs don't support null pointer arguments. The existing implementation of isInductionPHI requires this invariance and this patch should not regress it.

syzaara updated this revision to Diff 445579.Jul 18 2022, 11:35 AM
syzaara updated this revision to Diff 445583.Jul 18 2022, 11:39 AM
syzaara added inline comments.Jul 25 2022, 6:44 AM
llvm/lib/Analysis/IVDescriptors.cpp
1537

@fhahn can you please take a look for review? Thank you!