To fix PR27859, bail out if there is an instruction may throw.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I'm pretty sure this is wrong. It only considers calls in the same basic block as the store. However, the store could post-dominate a call to a function which never returns.
Instead, I suggest using llvm::isGuaranteedToTransferExecutionToSuccessor instead of the current, wrong, heuristic of "does this BB dominate all the exit blocks".
Due to the nature of llvm::isGuaranteedToTransferExecutionToSuccessor, I suggest that it's logic be factored out so that you can cache some of the intermediate results.
test/Transforms/LoopIdiom/unwind.ll | ||
---|---|---|
5–51 | There is no need to provide the definition of f. You could use my reduced testcase, I'm pretty sure it is minimal. |
test/Transforms/LoopIdiom/unwind.ll | ||
---|---|---|
5–51 | Targets like AArch64 do not generate attribute uwtable so that I include the definition of f. |
test/Transforms/LoopIdiom/unwind.ll | ||
---|---|---|
5–51 | Er, this testcase has an explicit triple. What does AArch64 have to do with anything? |
lib/Transforms/Scalar/LoopIdiomRecognize.cpp | ||
---|---|---|
392 | This check is in collectStores, which is run once per basic block... so this won't notice a call which throws in a different basic block ("for (...) { p[i] = 0; if (a) throwing_fn(); }"), | |
test/Transforms/LoopIdiom/unwind.ll | ||
19 | No reason to include the implementation of f in the testcase. |
Sorry for the long delay.
Just use computeLoopSafetyInfo (which calls isGuaranteedToTransferExecutionToSuccessor) to decide whether the loop may throw or not.
Please take a look.
The code looks fine. The comments could use a bit of refinement.
lib/Transforms/Scalar/LoopIdiomRecognize.cpp | ||
---|---|---|
220 | Useless comment. | |
223 | It would be useful to explain why this check is necessary. Among other things, it would be good to mention that existing transforms involve hoisting stores into the loop pre-header. |
Useless comment.