Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move insert point after PHI nodes. #794

Merged
merged 1 commit into from
Oct 16, 2020

Conversation

zoecarver
Copy link
Contributor

If replacing a PHI node with another instruction, make sure the insertion point is after the last PHI node in that block. This prevents the assertion described in #779.

@@ -0,0 +1,46 @@
; RUN: %opt -load %pass -souper -S -stats -o - %s 2>&1 | %FileCheck %s
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was having a bit of a hard time coming up with good tests. If I could tell souper to just run once, I think I could create a better test (that checks we replace a PHI instruction with an add, for example).

Other than that, I can't come up with an input program where the PHI node is replaced with a non-phi node, and the whole thing isn't optimized away at some point later.

@regehr
Copy link
Collaborator

regehr commented Oct 6, 2020

ahhh... thanks for looking into this! we just haven't had time. I'll look at the code tomorrow, but I think for now it's sufficient testing to include the original bug trigger as a regression test. we'll get plenty more testing using our existing fuzzers.

@regehr
Copy link
Collaborator

regehr commented Oct 7, 2020

@zhengyangl do you have time to review this request?

while (!InsertPoint->isTerminator() &&
isa<PHINode>(InsertPoint->getNextNode()))
InsertPoint = InsertPoint->getNextNode();
if (InsertPoint->isTerminator())
Copy link
Contributor

@zhengyang92 zhengyang92 Oct 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @zoecarver ,

Thanks for the patch! One concern: as stated in [1], after calling IRBuilder.SetInsertPoint(Instruction *I), the new instructions will be inserted before instruction I. In this case, InsertPoint should be the instruction just next to the last phi in that basic block, right? However, this code would make InsertPoint the last PHI and Instruction could still possibly be inserted between PHI nodes.

[1] https://llvm.org/doxygen/classllvm_1_1IRBuilderBase.html#ae72654261eee259da46249dc919b029c

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since IR builder is inserting before the ReplacedInst, it should work even when ReplacedInst is a terminator, right? Therefore, checking the terminator is not necessary here.

And Souper won't create Phis, the check I->K != Inst::Kind::Phi is not necessary here.

I think

if (ReplacedInst) {
  Instruction *InsertPoint = ReplacedInst;
  while (isa<PHINode>(InsertPoint) {
    InsertPoint = InsertPoint->getNextNode();
  }
  Builder.SetInsertPoint(InsertPoint);
}

should just do the work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll update it with your suggestion. I think it would be good to keep the isa<PHINode>(ReplacedInst->getNextNode()) check so that we don't unnecessarily update the InsertPoint, though.

If replacing a PHI node with another instruction, make sure the
insertion point is after the last PHI node in that block. This prevents
the assertion described in google#779.
@zhengyang92
Copy link
Contributor

Hi @zoecarver, one final note: if some replacement has Phi for ReplacedInst and a non-phi for the replacedInst->getNextNode, then we'll never reach the true branch, and by the definition of setInsertPoint() the new instruction would be inserted before the ReplaceInst (a phi node), which will cause trouble since we're trying to insert a non-phi instruction in the middle of the phi chunk.

if (ReplacedInst && isa<PHINode>(Replacement)) would be bug-free.

@zoecarver
Copy link
Contributor Author

Hi @zoecarver, one final note: if some replacement has Phi for ReplacedInst and a non-phi for the replacedInst->getNextNode, then we'll never reach the true branch, and by the definition of setInsertPoint() the new instruction would be inserted before the ReplaceInst (a phi node), which will cause trouble since we're trying to insert a non-phi instruction in the middle of the phi chunk.

Sorry for the delayed response. My reasoning is that ReplacedInst will always be removed after the new instruction is added. In this case, we don't want to change the InsertPoint unnecessarily because even though for a short period of time there will be a non-phi node before a phi node, the replaced phi node will be removed before the verifier ever runs.

@regehr
Copy link
Collaborator

regehr commented Oct 15, 2020

hey @zhengyangl are you OK with this patch now? it looks fine to me

@zhengyang92
Copy link
Contributor

LGTM

@regehr
Copy link
Collaborator

regehr commented Oct 16, 2020

thanks for the bugfix!

@regehr regehr merged commit 5d659bd into google:master Oct 16, 2020
@zoecarver
Copy link
Contributor Author

thanks for the bugfix!

Of course. Thanks (both of you) for reviewing/merging!

Jacarte pushed a commit to KTH/souper that referenced this pull request Dec 21, 2020
If replacing a PHI node with another instruction, make sure the
insertion point is after the last PHI node in that block. This prevents
the assertion described in google#779.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants