[SEH] Reimplement x64 SEH using WinEHPrepare
[oota-llvm.git] / test / CodeGen / X86 / seh-finally.ll
1 ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
2
3 @str_recovered = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
4
5 declare void @crash()
6
7 define i32 @main() {
8 entry:
9   invoke void @crash()
10           to label %invoke.cont unwind label %lpad
11
12 invoke.cont:                                      ; preds = %entry
13   %call = call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0))
14   call void @abort()
15   ret i32 0
16
17 lpad:                                             ; preds = %entry
18   %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
19           cleanup
20   %1 = extractvalue { i8*, i32 } %0, 0
21   %2 = extractvalue { i8*, i32 } %0, 1
22   %call2 = invoke i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0))
23           to label %invoke.cont1 unwind label %terminate.lpad
24
25 invoke.cont1:                                     ; preds = %lpad
26   resume { i8*, i32 } %0
27
28 terminate.lpad:                                   ; preds = %lpad
29   %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
30           catch i8* null
31   call void @abort()
32   unreachable
33 }
34
35 ; CHECK-LABEL: main:
36 ; CHECK: .seh_handlerdata
37 ; CHECK-NEXT: .long 1
38 ; CHECK-NEXT: .long .Ltmp0@IMGREL
39 ; CHECK-NEXT: .long .Ltmp1@IMGREL
40 ; CHECK-NEXT: .long main.cleanup@IMGREL
41 ; CHECK-NEXT: .long 0
42
43 ; CHECK-LABEL: main.cleanup:
44 ; CHECK: callq puts
45 ; CHECK: retq
46
47 declare i32 @__C_specific_handler(...)
48
49 declare i32 @puts(i8*)
50
51 declare void @abort()