CodeExtracting a block that references a blockadress breaks blockaddress usage by attaching them to other functions.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
@davide: while writing the test case, I came up with a better solution, I'll upload this as soon as it's finished.
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? |
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 |
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?
> 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.
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' ?
../lib/Transforms/Utils/CodeExtractor.cpp | ||
---|---|---|
75 ↗ | (On Diff #102992) | Remove this comment. |
80 ↗ | (On Diff #102992) | Can you combine insert and count call, i.e, check the second member of the returned pair of 'insert'? |
81 ↗ | (On Diff #102992) | Remove braces. |
82 ↗ | (On Diff #102992) | return false? |
84 ↗ | (On Diff #102992) | 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 ↗ | (On Diff #102992) | Need a test case covering use of block address in extracted region. |
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. |