This is an archive of the discontinued LLVM Phabricator instance.

[WinEH] Add llvm.eh.exceptionpointer intrinsic
ClosedPublic

Authored by JosephTremoulet on Sep 1 2015, 8:57 AM.

Details

Summary

This intrinsic can be used to extract a pointer to the exception caught by
a given catchpad. Its argument has token type and must be a catchpad.

Also clarify ExtendingLLVM documentation regarding overloaded intrinsics.

Diff Detail

Event Timeline

JosephTremoulet retitled this revision from to [WinEH] Add llvm.eh.padparam intrinsic.
JosephTremoulet updated this object.
JosephTremoulet added a subscriber: llvm-commits.
rnk edited edge metadata.Sep 1 2015, 9:28 AM

This seems like it's kind of splitting the difference between extracttoken and specific intrinsics. Based on your proposal, I was envisioning having a family of intrinsics like:

declare i32 @llvm.eh.exceptioncode(token)
declare i8* @llvm.eh.exceptioninfo(token) ; I guess this is for SEH filters only, which we don't have yet...
declare i8 @llvm.eh.abnormaltermination(token)
declare i32 @llvm.eh.exceptionstate(token)

Then we don't need the llvm_any_ty mangling, and the IR seems more readable.

What use cases do you have for the additional parameters to padparam? If the extra parameters are used like an enum, where the backend has to switch on it and use custom code for different cases, then I think individual intrinsics are the way to go. If the extra parameters are more like an index into a list of register parameters (RCX, RDX, R8, R9, ...) or an index into argument stack slots, then llvm.eh.padparam seems like a reasonable approach.

We should also see what Sanjoy needs for GC.

rnk added a reviewer: sanjoy.Sep 1 2015, 9:28 AM

Yes, it was ironic that eh.padparam ended up with the fully-general signature. That was simply an attempt to match the "look-and-feel" of the other EH operators/intrinsics, which are typically abstracted over the personality function.

What use cases do you have for the additional parameters to padparam?

I wasn't planning on using any in LLILC (the only extraction I need is to get an exception pointer from a catchpad), I just included them in the opcode signature to give flexibility for other personalities.

If the extra parameters are used like an enum, where the backend has to switch on it and use custom code for different cases, then I think individual intrinsics are the way to go. If the extra parameters are more like an index into a list of register parameters (RCX, RDX, R8, R9, ...) or an index into argument stack slots, then llvm.eh.padparam seems like a reasonable approach.

I agree with that view. I was imagining an outer switch on personality function, and that the selector arguments if used would likely index into a parameter list.

I'm certainly not wedded to keeping padparam this general. The specific signature that I need is exception_aggr addrspace(1)* @llvm.eh.intrinsicname() (or I could get by with i8 addrspace(1)* @llvm.eh.intrinsicname() and bitcasts). I guess for my specific case intrinsicname would be get_clr_exception or something. If you'd prefer that, let me know what you think the name should be and whether you want any of the ones you listed included in this patch, and I'll be happy to change it.

rnk added a comment.Sep 1 2015, 10:51 AM

I'm certainly not wedded to keeping padparam this general. The specific signature that I need is exception_aggr addrspace(1)* @llvm.eh.intrinsicname() (or I could get by with i8 addrspace(1)* @llvm.eh.intrinsicname() and bitcasts). I guess for my specific case intrinsicname would be get_clr_exception or something. If you'd prefer that, let me know what you think the name should be and whether you want any of the ones you listed included in this patch, and I'll be happy to change it.

I guess the addressspace(1) thing has to be baked into the signature for you, so we can't get by with i8* @llvm.eh.exceptionpointer(token) and addresspacecast. How about making it llvm_any_ty and using i8 addressspace(1) * @llvm.eh.exceptionpointer.p1i8(token)?

How about making it llvm_any_ty and using i8 addressspace(1) * @llvm.eh.exceptionpointer.p1i8(token)?

I can do something along those lines, sure. Two questions:

  1. If it's always going to be a pointer type, would it be better to use llvm_anyptr_ty and i8 addrspace(1)* @llvm.eh.exceptionpointer.p1(token)?
  2. OTOH, if it's not always going to be a pointer type (e.g. if you're going to use the same one for SEH exception codes), should the name be something like llvm.eh.get_exception that doesn't include pointer?
rnk added a comment.Sep 1 2015, 1:21 PM

How about making it llvm_any_ty and using i8 addressspace(1) * @llvm.eh.exceptionpointer.p1i8(token)?

I can do something along those lines, sure. Two questions:

  1. If it's always going to be a pointer type, would it be better to use llvm_anyptr_ty and i8 addrspace(1)* @llvm.eh.exceptionpointer.p1(token)?

Sounds good.

  1. OTOH, if it's not always going to be a pointer type (e.g. if you're going to use the same one for SEH exception codes), should the name be something like llvm.eh.get_exception that doesn't include pointer?

If/when we add SEH filter funclets, we'll need separate constructs for exception_info() and exception_code(). In anticipation, we should probably use llvm.eh.exceptioncode for the SEH code.

JosephTremoulet retitled this revision from [WinEH] Add llvm.eh.padparam intrinsic to [WinEH] Add llvm.eh.exceptionpointer intrinsic.
JosephTremoulet updated this object.
  • Make the intrinsic and its signature more narrow, per review feedback

I've made the updates per your suggestion (unless I've misunderstood the suggestion... :]).

  • fix typo in doc
rnk accepted this revision.Sep 1 2015, 6:40 PM
rnk edited edge metadata.

lgtm

This revision is now accepted and ready to land.Sep 1 2015, 6:40 PM
sanjoy edited edge metadata.Sep 1 2015, 11:26 PM
In D12533#237397, @rnk wrote:

We should also see what Sanjoy needs for GC.

We'd eventually (i.e. I cannot commit to a timeframe right now) change
statepoints to return a token, and change the existing gc_result
and gc_relocate family of intrinsics to consume the token produced
by the statepoint call / invoke. Currently we're using an i32
instead of a token, and that's unsound.

I expect the end result for the gc_relocate and gc_result
intrinsics to look fairly similar to llvm.eh.exceptionpointer.

docs/ExceptionHandling.rst
415

Should there be a verifier rule checking that only catchpads feed into this intrinsic?

JosephTremoulet edited edge metadata.
  • add verifier rule and test
JosephTremoulet marked an inline comment as done.Sep 2 2015, 8:29 AM
JosephTremoulet added inline comments.
docs/ExceptionHandling.rst
415

Yes; updated to include this.

sanjoy added a comment.Sep 2 2015, 3:57 PM
  • add verifier rule and test

LGTM.

JosephTremoulet marked an inline comment as done.