Hi,
I’m trying to get exception handling working in my compiler targetting LLVM. I’ve been working from the LLVM exception handling documentation (including http://llvm.org/docs/ExceptionHandling.html and http://wiki.llvm.org/HowTo:_Build_JIT_based_Exception_mechanism) and looking at g+±llvm’s output.
I’ve been trying to get a minimal test function to work, which simply invokes _Unwind_RaiseException with a single clean-up landing pad. However. when I run it my personality function is not getting called - _Unwind_RaiseException simply returns apparently doing nothing. Looking at the x86-64 assembly output from llc, I can see this is happening because the personality function is not getting into the DWARF eh table (the landing pad is there though).
I’m stumped as to why not. I’d be grateful if anyone can point out what I’m doing wrong here:
define i32 @_ZN4N0014Main5test5EN2IO6WriterEiA_l(%6*, %4*, i32, %33*) {
entry:
%err = alloca %4* ; <%4**> [#uses=1]
%count = alloca i32 ; <i32*> [#uses=1]
%e = alloca %33* ; <%33**> [#uses=2]
%this = alloca %6* ; <%6**> [#uses=1]
%.ex_value = alloca i8* ; <i8**> [#uses=1]
%.ex_value_l = alloca i8* ; <i8**> [#uses=0]
%.ex_type = alloca i64 ; <i64*> [#uses=1]
br label %4
; :4 ; preds = %entry
store %6* %0, %6** %this
store %4* %1, %4** %err
store i32 %2, i32* %count
store %33* %3, %33** %e
br label %.try_body
.try_body: ; preds = %4
%5 = load %33** %e ; <%33*> [#uses=1]
%6 = getelementptr inbounds %33* %5, i32 0, i32 2, i32 0 ; <i64*> [#uses=1]
%7 = invoke i8* (…)* bitcast (i32 (%struct._Unwind_Exception*)* @_Unwind_RaiseException to i8* (…))(i64 %6)
to label %8 unwind label %.finally_pad ; <i8*> [#uses=0]
; :8 ; preds = %.try_body
br label %.finally_handler
.finally_pad: ; preds = %.try_body
%9 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
store i8* %9, i8** %.ex_value
%10 = call i64 (i8*, i8*, …)* @llvm.eh.selector.i64(i8* %9, i8* bitcast (i32 (i32, i32, i64, %struct._Unwind_Exception*, %struct._Unwind_Context*)* @__l_personality to i8*)) ; [#uses=1]
%11 = icmp eq i64 %10, 0 ; [#uses=1]
%12 = select i1 %11, i64 0, i64 1 ; [#uses=1]
store i64 %12, i64* %.ex_type
br label %.finally_handler
.finally_handler: ; preds = %.finally_pad, %8
%13 = call i8* (…)* bitcast (i32 (i8*, …)* @printf to i8* (…))(i8 getelementptr ([9 x i8]* @__string_27, i32 0, i32 0)) ; <i8*> [#uses=0]
ret i32 0
}
Thanks in advance,
– James Williams
PS: Thanks to all LLVM contributers for such a well designed IR and code generation library. Switching my compiler from its existing back end to LLVM has so far been incredibly quick and easy - a matter of a few evenings and a couple of weekends!