Siddharth Bhat via llvm-dev
2017-Jun-24 15:21 UTC
[llvm-dev] musttail & alwaysinline interaction
Consider this program: @globalSideEffect = global i32 0 define void @tobeinlined() #0 { entry: store i32 3, i32* @globalSideEffect, align 4 musttail call fastcc void @tailcallee(i32 3) ret void } define fastcc void @tailcallee(i32 %i) { entry: call void @tobeinlined() ret void } attributes #0 = { alwaysinline } Clearly, if this is processed with opt -alwaysinline, it will lead to a correct tail call since the call to "tobeinlined" will be inlined. However, because opt checks for the correctness of the module when it is being loaded, it fails the verifyModule() check with: cannot guarantee tail call due to mismatched parameter counts musttail call fastcc void @tailcallee(i32 3) opt: prelude.inlined.ll: error: input module is broken! These are just experiment, but I suspect that I will have the same problem when I am constructing IR with the LLVM API: That is, the verifyModule sanity check will cause the IR to be considered illegal, *even though the final IR that would have been generated will be correct.* What is the correct solution to this when I'm programatically generating IR? I was considering: 1. generate calls with tail, not musttail 2. Apply AlwaysInline pass to Module 3. Walk module and replace tail with musttail 4. Apply VerifyModule to sanity check However, that seems like somewhat of a hack. Is there a nicer solution? Will what I'm trying "just work"? Thanks, ~Siddharth -- Sending this from my phone, please excuse any typos! -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170624/4e72f235/attachment.html>
Philip Reames via llvm-dev
2017-Jul-01 21:07 UTC
[llvm-dev] musttail & alwaysinline interaction
The IR you provide is actually incorrect. The "tobeinlined" function is external, so there's no way even in theory to assert that it's always inlined. We could consider relaxing the verifier to allow this case, but doing that seems problematic. In particular, why stop at one level of inlining? We really don't want the verify to have to be walking back through the entire call graph to verify the required property. We could also relax the definition of mustail. To do this, we'd need to carefully consider whether there's a tweak to our definition of musttail which is sufficient without loosing to much error diagnostics or optimization power. Any suggestions on specific revisions here? The current restriction on mustail -- specifically matching signatures -- is stronger than it needs to be in. You could consider enhancing the backends to lower tailcalls with signature mismatches and then extend the verify to allow those cases. That would be a way around your problem indirectly. Philip On 06/24/2017 08:21 AM, Siddharth Bhat via llvm-dev wrote:> Consider this program: > > @globalSideEffect = global i32 0 > > define void @tobeinlined() #0 { > entry: > store i32 3, i32* @globalSideEffect, align 4 > musttail call fastcc void @tailcallee(i32 3) > ret void > } > > define fastcc void @tailcallee(i32 %i) { > entry: > call void @tobeinlined() > ret void > > } > > attributes #0 = { alwaysinline } > > Clearly, if this is processed with opt -alwaysinline, it will lead to > a correct tail call since the call to"tobeinlined" will be inlined. > > However, because opt checks for the correctness of the module when it > is being loaded, it fails the verifyModule() check with: > > > cannot guarantee tail call due to mismatched parameter counts > musttail call fastcc void @tailcallee(i32 3) > opt: prelude.inlined.ll: error: input module is broken! > > These are just experiment, but I suspect that I will have the same > problem when I am constructing IR with the LLVM API: That is, the > verifyModule sanity check will cause the IR to be considered illegal, > /even though the final IR that would have been generated will be correct./ > / > / > What is the correct solution to this when I'm programatically > generating IR? > > I was considering: > > 1. generate calls with tail, not musttail > 2. Apply AlwaysInline pass to Module > 3. Walk module and replace tail with musttail > 4. Apply VerifyModule to sanity check > > However, that seems like somewhat of a hack. Is there a nicer > solution? Will what I'm trying "just work"? > > Thanks, > ~Siddharth > > -- > Sending this from my phone, please excuse any typos! > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170701/fb87d1b3/attachment.html>