Eduardo Souza via llvm-dev
2020-Sep-15 08:37 UTC
[llvm-dev] RewriteStatepointsForGC and Invoke
Hi all, I have been trying to use LLVM's GC infrastructure (Statepoints) and ran into an issue when using exception handling. The problem happens when I use an invoke instruction to support exception handling, and try to apply the pass RewriteStatepointsForGC to produce stackmaps. I was able to create a minimal example using the example in the documentation of RewriteStatepointsForGC: declare void ()* @foo() declare i8* @__gxx_personality_v0() define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj) gc "statepoint-example" personality i8* ()* @__gxx_personality_v0 { blk_entry: invoke void ()* @foo() to label %blk_normal unwind label %blk_exc blk_normal: ret i8 addrspace(1)* %obj blk_exc: %res1 = landingpad { i8*, i32 } catch i8* null ret i8 addrspace(1)* %obj } The pass is suppose to rewrite the invoke call into a call to *llvm.experimental.gc.statepoint*, producing a token, and the token can be used in *llvm.experimental.gc.relocate*, to get the relocated pointer. For a normal call, the IR after the pass should look like: blk_entry: %statepoint_token = call token (i64, i32, void ()* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0f_isVoidff(i64 2882400000, i32 0, void ()* ()* @foo, i32 0, i32 0, i32 0, i32 0, i8 addrspace(1)* %obj) %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%obj, %obj) br label %blk_normal blk_normal: ; preds = %blk_entry ret i8 addrspace(1)* %obj.relocated However, since I'm using an invoke, I do not have access to the token returned by the call to *llvm.experimental.gc.statepoint* in *blk_exc*, making it not possible to relocate *%obj* when an exception is thrown. When running the pass on the initial example I get: Call parameter type does not match function signature! %res1 = landingpad { i8*, i32 } catch i8* null token %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8({ i8*, i32 } %res1, i32 7, i32 7) ; (%obj, %obj) LLVM ERROR: Broken function found, compilation aborted! I assume the pass does not consider the invoke scenario, but even then, I would not know how to fix this issue myself, since I cannot access *%statepoint_token* in the exception block. Is this a known issue? Is there any way to work around it that I might not be seeing? Thanks in advance, -- Luis Eduardo de Souza Amorim -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200915/01319eb8/attachment.html>
Denis Antrushin via llvm-dev
2020-Sep-15 16:54 UTC
[llvm-dev] RewriteStatepointsForGC and Invoke
There is a warning in llvm docs about your problem (https://llvm.org/docs/Statepoints.html#id33) : ``` Relocations along exceptional paths are currently broken in ToT. In particular, there is current no way to represent a rethrow on a path which also has relocations. See this llvm-dev discussion for more detail. ``` (What's ToT? I don't know) And it points to this topic: https://groups.google.com/forum/#!topic/llvm-dev/AE417XjgxvI Basically it works for cleanup landing pads only and should looks like this: ``` blk_exc: %res1 = landingpad token cleanup ret i8 addrspace(1)* %obj ``` On 15.09.2020 11:37, Eduardo Souza via llvm-dev wrote:> Hi all, > > I have been trying to use LLVM's GC infrastructure (Statepoints) and ran into an issue when using exception handling. > The problem happens when I use an invoke instruction to support exception handling, and try to apply the pass RewriteStatepointsForGC to produce stackmaps. > I was able to create a minimal example using the example in the documentation of RewriteStatepointsForGC: > > declare void ()* @foo() > declare i8* @__gxx_personality_v0() > define i8 addrspace(1)* @test1(i8 addrspace(1)* %obj) > gc "statepoint-example" personality i8* ()* @__gxx_personality_v0 { > blk_entry: > invoke void ()* @foo() to label %blk_normal unwind label %blk_exc > blk_normal: > ret i8 addrspace(1)* %obj > blk_exc: > %res1 = landingpad { i8*, i32 } > catch i8* null > ret i8 addrspace(1)* %obj > } > > The pass is suppose to rewrite the invoke call into a call to *llvm.experimental.gc.statepoint*, producing a token, and the token can be used in *llvm.experimental.gc.relocate*, to get the relocated pointer. For a normal call, the IR after the pass should look like: > > blk_entry: > %statepoint_token= call token (i64, i32,void ()* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0f_isVoidff(i642882400000, i320,void ()* ()* @foo, i320, i320, i320, i320, i8addrspace(1)* %obj) > %obj.relocated= call coldcc i8addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i327, i327); (%obj, %obj) > br label %blk_normal > > blk_normal: ; preds = %blk_entry > ret i8addrspace(1)* %obj.relocated > > However, since I'm using an invoke, I do not have access to the token returned by the call to *llvm.experimental.gc.statepoint* in *blk_exc*, making it not possible to relocate *%obj* when an exception is thrown. When running the pass on the initial example I get: > > Call parameter type does not match function signature! > %res1 = landingpad { i8*, i32 } > catch i8* null > token %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8({ i8*, i32 } %res1, i32 7, i32 7) ; (%obj, %obj) > LLVM ERROR: Broken function found, compilation aborted! > > > I assume the pass does not consider the invoke scenario, but even then, I would not know how to fix this issue myself, since I cannot access *%statepoint_token* in the exception block. > Is this a known issue? Is there any way to work around it that I might not be seeing? > > Thanks in advance, > > -- > Luis Eduardo de Souza Amorim > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >