This is an archive of the discontinued LLVM Phabricator instance.

Prevent outlining of basicblock that uses BlockAddress
ClosedPublic

Authored by serge-sans-paille on Jun 2 2017, 9:38 AM.

Details

Summary

CodeExtracting a block that references a blockadress breaks blockaddress usage by attaching them to other functions.

Diff Detail

Repository
rL LLVM

Event Timeline

davide edited edge metadata.Jun 2 2017, 11:28 AM

testcase?

@davide: while writing the test case, I came up with a better solution, I'll upload this as soon as it's finished.

serge-sans-paille retitled this revision from Prevent Outlining of basic blocks that reference a BasicBlockAddress to Correctly remap BlockAddress when using CodeExtractor.Jun 4 2017, 8:51 AM
serge-sans-paille edited the summary of this revision. (Show Details)

@davide Test case added, providing a fix instead of a guard.

@davide Does the new change look correct to you?

davide added inline comments.
test/Transforms/CodeExtractor/BlockAddressreference.ll
1–2 ↗(On Diff #101356)

This test has no check lines, so I guess it will pass also without your change [unless it crashed before] ? Is there a better way of testing?

davidxl edited edge metadata.Jun 10 2017, 9:34 PM

It is probably not legal to outline a BB with BB's address captured, so your previous version is better.

lib/Transforms/Utils/CodeExtractor.cpp
75 ↗(On Diff #101229)

You can use BasicBlock::hasAddressTaken method

@davidxl

It is probably not legal to outline a BB with BB's address captured,

I don't see anything in the lang ref that goes in that way. You could save the blockaddress in an array at some point in the program, and use it later on.

test/Transforms/CodeExtractor/BlockAddressreference.ll
1–2 ↗(On Diff #101356)

@davide: yeah, it was crashing before, illegaly referencing blockaddress(@asterix, %for.cond) that no longer existed because of the outlining. This patch remaps it to @blockaddress(@outlined_function, %for.cond).

This is assuming the referencing the saved addresses is only within the extracted function, but reference to block addresses from outside the parent function is illegal. How do you prevent the original function from branch into the middle of the outlined function?

@davidxl

>  reference to block addresses from outside the parent function is illegal

If that's true, then my first patch was indeed better than this one. Can you point me to the relevant spec section?

The spec probably needs update, but I remember inliner or function cloning does something to avoid this. +cc Chandler for comments.

sanjoy added a subscriber: sanjoy.Jun 11 2017, 9:48 PM

The spec probably needs update, but I remember inliner or function cloning does something to avoid this. +cc Chandler for comments.

Are you looking for this (emphasis mine): "The ‘indirectbr‘ instruction implements an indirect branch to a label within the current function, whose address is specified by “address”. Address must be derived from a blockaddress constant."

That looks like it - it is in the indirectbr clause, so it might be a good idea to state something in the section describing 'blockaddress' ?

serge-sans-paille retitled this revision from Correctly remap BlockAddress when using CodeExtractor to Prevent outlining of basicblock that uses BlockAddress.
serge-sans-paille edited the summary of this revision. (Show Details)

@davidxl , should be okay like this.

davidxl added inline comments.Jun 26 2017, 9:32 AM
../lib/Transforms/Utils/CodeExtractor.cpp
75

Remove this comment.

80

Can you combine insert and count call, i.e, check the second member of the returned pair of 'insert'?

81

Remove braces.

82

return false?

84

You don't need to check the operands of instructions not in the BB set to be extracted. Guard this with

if (Curr->getParent() == &BB)

../test/Transforms/CodeExtractor/BlockAddressreference.ll
1

Need a test case covering use of block address in extracted region.

serge-sans-paille marked 5 inline comments as done.

@davidxl, all comments taken into account, thanks *a lot* for your review.

This revision is now accepted and ready to land.Jun 27 2017, 10:03 AM
This revision was automatically updated to reflect the committed changes.
efriedma added inline comments.
lib/Transforms/Utils/CodeExtractor.cpp
79 ↗(On Diff #104184)

I'm not sure I follow this check.

You can't extract a basic block whose terminator is an indirectbr; in general, you can't efficiently break the relevant CFG edges. Similarly, you can't extract a block with an indirectbr predecessor. And extracting a block whose address is taken is likely to lead to unexpected results in other cases for code which abuses block addresses for other uses (like the Linux kernel).

But I can't see why you would want to block extracting a basic block just because it refers to a blockaddress, or a global variable which contains a blockaddress.