[llvm-dev] setjmp/longjmp and volatile stores, but non-volatile loads
Jonas Maebe via llvm-dev
llvm-dev at lists.llvm.org
Wed Dec 21 12:02:08 PST 2016
On 21/12/16 19:54, Reid Kleckner wrote:
> On Sun, Dec 18, 2016 at 11:58 PM, Jonas Maebe <jonas-devlists at watlock.be
> <mailto:jonas-devlists at watlock.be>> wrote:
>
> Actually, there's another —even more fundamental— problem: the longjmp
> will always restore the non-volatile registers to the contents they had
> at the start of the try-block, which is not what LLVM expects when
> entering an SEH-based landing pad.
>
> The SjLjEHPrepare pass tries to deal with this by demoting all values
> live across EH edges to the stack. This should also eliminate those phis
> from landingpad blocks. Check
> out TargetPassConfig::addPassesToHandleExceptions() and make sure you
> run that pass.
Thanks for the suggestion! Unfortunately,
1) it also inserts calls to _Unwind_SjLj_Register/_Unwind_SjLj_Unregister
2) it still inserts phis, and also the equivalent for memory-based
synchronisation in landingpads:
Lj15:
%tmp.6.1.reg2mem.0 = phi i32 [ %reg.1_66, %Lj47 ], [ %reg.1_66, %Lj46
], [ %reg.1_66, %Lj45 ], [ %reg.1_66, %Lj44 ], [ %reg.1_66, %Lj43 ], [
%reg.1_66, %Lj42 ], [ %reg.1_66, %Lj41 ], [ %reg.1_66, %Lj40 ], [
%reg.1_66, %Lj32 ], [ %reg.1_66, %Lj38 ], [ %reg.1_6
6, %Lj37 ], [ %reg.1_66, %Lj36 ], [ %reg.1_66, %Lj35 ], [ %reg.1_66,
%Lj34 ], [ %reg.1_66, %Lj31 ], [ %tmp.6.0, %Lj29 ], [ %tmp.6.0, %Lj28 ],
[ %tmp.6.0, %Lj27 ], [ %tmp.6.0, %Lj26 ], [ %tmp.6.0, %Lj25 ], [
%tmp.6.0, %Lj22 ], [ %tmp.6.0, %Lj20 ]
%reg.1_116 = landingpad %"typ.PROGRAM.$llvmstruct$d00000004i32"
catch i8* null
%exception_gep = getelementptr { i8*, i32, [4 x i32], i8*, i8*, [5 x
i8*] }, { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }* %fn_context, i64
0, i32 2, i64 0
%exn_val = load volatile i32, i32* %exception_gep, align 4
%exn_selector_gep = getelementptr { i8*, i32, [4 x i32], i8*, i8*, [5
x i8*] }, { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }* %fn_context, i64
0, i32 2, i64 1
%exn_selector_val = load volatile i32, i32* %exn_selector_gep, align 4
br label %Lj13
; label where our setjmp branches to
Lj13: ; preds = %0, %Lj15
%tmp.6.2 = phi i32 [ 0, %0 ], [ %tmp.6.1.reg2mem.0, %Lj15 ]
Additionally, if you just run that pass in opt in addition to -O1
(-sjljehprepare -O1), then calling llc on the result will fail with an
assert:
Assertion failed: (MI.isEHLabel() && "expected EH_LABEL"), function
EmitSjLjDispatchBlock, file
/Data/imacdev/llvm/lib/Target/X86/X86ISelLowering.cpp, line 25273.
That's with trunk at 290046; with 3.9 I get errors about invalid relocation
calculations instead. So it seems like this pass cannot be used in
isolation.
I've posted the full unoptimized code for the test module at
http://pastebin.com/PztgYGnF (although to run it after compiling, you'd
need more).
Jonas
More information about the llvm-dev
mailing list