I've never used phabricator, so sorry if I do this wrong.
This is originally from:
https://bugs.llvm.org/show_bug.cgi?id=37788
---8<---
Over the last few days I have been experimenting with inserting stackmaps from
the Rust compiler.
After inserting some calls (not invokes) to llvm.experimental.stackmap into rustc's llvm
codegen, and then allowing the compiler to build itself using this change, I
was surprised to see:
Cannot invoke an intrinsic other than donothing, patchpoint, statepoint, coro_resume or coro_destroy invoke void (i64, i32, ...%) @llvm.experimental.stackmap(i64 1, i32 0) to label 13
As I understand, this is LLVM's way of saying, you can't invoke (expecting a
possible exception) an intrinsic which cannot raise an exception.
Having spoke to one of the Rust developers about this, and after trying
a few things, it seems that LLVM's inlining pass is itself allowing calls to
the stackmap intrinsic to be translated to invokes. Then the verifier rejects
the resulting code.
We suspect that the fix is as follows:
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index a2a1f26292c..9bbe22645ac 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -720,8 +720,7 @@ def int_invariant_group_barrier : Intrinsic<[llvm_anyptr_ty], //===------------------------ Stackmap Intrinsics -------------------------===// // def int_experimental_stackmap : Intrinsic<[], - [llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty], - [Throws]>; + [llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty], []>; def int_experimental_patchpoint_void : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_ptr_ty, llvm_i32_ty,
In other words, remove Throws from the signature of int_experimental_stackmap.
With this patch applied, I managed to run a stage 2 rustc build without the
verifier getting upset.
--->8---
Since then I've also checked if tests work. They all pass.