Skip to content

CloneFunction: Do not delete blocks with address taken #134209

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

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Apr 3, 2025

If a block with a single predecessor also had its address taken,
it was getting deleted in this post-inline cleanup step. This would
result in the blockaddress in the resulting function getting deleted
and replaced with inttoptr 1.

This fixes one bug required to permit inlining of functions with blockaddress
uses.

At the moment this is not testable (at least without an annoyingly complex
unit test), and is a pre-bug fix for future patches. Functions with
blockaddress uses are rejected in isInlineViable, so we don't get this far
with the current InlineFunction uses (some of the existing cases seem to
reproduce this part of the rejection logic, like PartialInliner). This
will be tested in a pending llvm-reduce change.

Prerequisite for #38908

If a block with a single predecessor also had its address taken,
it was getting deleted in this post-inline cleanup step. This would
result in the blockaddress in the resulting function getting deleted
and replaced with inttoptr 1.

This fixes one of (at least?) two bugs required to permit inlining of
functions with blockaddress uses.

At the moment this is not testable (at least without an annoyingly complex
unit test),  and is a pre-bug fix for future patches. Functions with
blockaddress uses are rejected in isInlineViable, so we don't get this far
with the current InlineFunction uses (some of the existing cases seem to
reproduce this part of the rejection logic, like PartialInliner). This
will be tested in a pending llvm-reduce change.

Prerequisite for #38908
@arsenm arsenm added the ipo Interprocedural optimizations label Apr 3, 2025 — with Graphite App
Copy link
Contributor Author

arsenm commented Apr 3, 2025

@arsenm arsenm marked this pull request as ready for review April 3, 2025 06:59
@llvmbot
Copy link
Member

llvmbot commented Apr 3, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

Changes

If a block with a single predecessor also had its address taken,
it was getting deleted in this post-inline cleanup step. This would
result in the blockaddress in the resulting function getting deleted
and replaced with inttoptr 1.

This fixes one of (at least?) two bugs required to permit inlining of
functions with blockaddress uses.

At the moment this is not testable (at least without an annoyingly complex
unit test), and is a pre-bug fix for future patches. Functions with
blockaddress uses are rejected in isInlineViable, so we don't get this far
with the current InlineFunction uses (some of the existing cases seem to
reproduce this part of the rejection logic, like PartialInliner). This
will be tested in a pending llvm-reduce change.

Prerequisite for #38908


Full diff: https://github.com/llvm/llvm-project/pull/134209.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/CloneFunction.cpp (+1-1)
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index e58585705e82f..9387797019023 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -928,7 +928,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
     }
 
     BasicBlock *Dest = BI->getSuccessor(0);
-    if (!Dest->getSinglePredecessor()) {
+    if (!Dest->getSinglePredecessor() || Dest->hasAddressTaken()) {
       ++I;
       continue;
     }

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM, in that this is consistent with MergeBlockIntoPredecessor behavior.

(I think technically it is legal to ignore the blockaddress in this case, because it is only specified to be meaningful in conjunction with indirectbr, where this fold would not apply. But given the ways the linux kernel abuses block labels, that ship has already sailed.)

@arsenm
Copy link
Contributor Author

arsenm commented Apr 3, 2025

(I think technically it is legal to ignore the blockaddress in this case, because it is only specified to be meaningful in conjunction with indirectbr,

For the ultimate usage, but it still needs to be passed around as an opaque value to be delivered to an eventual indirectbr use. The langref also says you can use as an inlineasm operand

@arsenm
Copy link
Contributor Author

arsenm commented Apr 3, 2025

This fixes one of (at least?) two bugs required to permit inlining of functions with blockaddress uses.

This might have been just one bug, the main issue I was trying to fix disappears with this alone

@regehr
Copy link
Contributor

regehr commented Apr 3, 2025

LGTM!

Copy link
Contributor Author

arsenm commented Apr 3, 2025

Merge activity

  • Apr 3, 12:51 PM EDT: A user started a stack merge that includes this pull request via Graphite.
  • Apr 3, 12:52 PM EDT: A user merged this pull request with Graphite.

@arsenm arsenm merged commit a54736a into main Apr 3, 2025
14 of 16 checks passed
@arsenm arsenm deleted the users/arsenm/clone-function-fix-folding-blocks-with-address-taken branch April 3, 2025 16:52
@@ -928,7 +928,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
}

BasicBlock *Dest = BI->getSuccessor(0);
if (!Dest->getSinglePredecessor()) {
if (!Dest->getSinglePredecessor() || Dest->hasAddressTaken()) {
Copy link
Member

Choose a reason for hiding this comment

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

perhaps worth updating the comment block on L918-L921?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ipo Interprocedural optimizations llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants