This is an archive of the discontinued LLVM Phabricator instance.

[ThinLTO] Disallow importing for functions with indir branch to block address
ClosedPublic

Authored by wenlei on Jul 27 2021, 6:24 PM.

Details

Summary

We don't allowing inlining for functions with blockaddress with uses other than strictly callbr. This is because if the blockaddress escapes the function via a global variable, inlining may lead to an invalid cross-function reference.

We check against such cases during inlining, however the check can fail for ThinLTO post-link because CFG simplification can incorrectly removes blocks based on wrong block reachability.

When we import a function with blockaddress taken in a global variable but without importing that variable, we won't go through value mapping to reflect the real address-taken-ness of the cloned blocks. For the imported clone, this leads to blocks reachable from indirect branch through global variable being incorrectly treated as unreachable and removed by SimplifyCFG.

Since inlining for such cases shouldn't be allowed in the first place, I'm marking them as ineligible for importing during pre-link to save the problem of missing address-taken-ness of imported clone as well as bad DCE and inlining.

Diff Detail

Event Timeline

wenlei created this revision.Jul 27 2021, 6:24 PM
wenlei requested review of this revision.Jul 27 2021, 6:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2021, 6:24 PM
wenlei added inline comments.Jul 27 2021, 6:27 PM
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
275

This logic is from InlineCost.cpp, but I'm not sure in what case do we have an indirect call to a block label?

wmi added inline comments.Jul 28 2021, 9:19 AM
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
275

Here is the only usage of CallBrInst in clang: https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/CGStmt.cpp#L2282, and it is used for gcc inline asm extension: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels

wenlei added inline comments.Jul 28 2021, 9:31 AM
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
275

Ok, thanks for the pointer. In that case, I think it's indeed safe to allow CallBrInst to block address for inlining and importing.

tejohnson accepted this revision.Jul 28 2021, 9:39 AM

LGTM with a test fix below.

llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
11

This only checks that there isn't an imported copy of bar defined after the imported copy of foo. Either add the same CHECK-NOT prior to the CHECK for foo, or make it a positive sense check for the declare of bar. Probably the latter is cleaner.

This revision is now accepted and ready to land.Jul 28 2021, 9:39 AM
wenlei updated this revision to Diff 362448.Jul 28 2021, 10:32 AM

Fix test to use positive check.

wenlei added inline comments.Jul 28 2021, 10:33 AM
llvm/test/ThinLTO/X86/globals-import-blockaddr.ll
11

Good catch, changed to positive check.