1; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s --check-prefix=NUM
2; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s --check-prefix=SJLJ
3
4; NUM-COUNT-3: endbr64
5
6;SJLJ:       main:                                  # @main
7;SJLJ-NEXT: .Lfunc_begin0:
8;SJLJ-NEXT: # %bb.0:                                # %entry
9;SJLJ-NEXT:         endbr64
10;SJLJ-NEXT:         pushq   %rbp
11;SJLJ:               callq   _Unwind_SjLj_Register
12;SJLJ-NEXT: .Ltmp0:
13;SJLJ-NEXT:         callq   _Z3foov
14;SJLJ-NEXT: .Ltmp1:
15;SJLJ-NEXT: # %bb.1:                                # %invoke.cont
16;SJLJ-NEXT:         movl
17;SJLJ-NEXT: .LBB0_7:                                # %return
18;SJLJ:               callq   _Unwind_SjLj_Unregister
19;SJLJ:               retq
20;SJLJ-NEXT: .LBB0_9:
21;SJLJ-NEXT:         endbr64
22;SJLJ-NEXT:         movl
23;SJLJ-NEXT:         cmpl
24;SJLJ-NEXT:         jb      .LBB0_10
25;SJLJ-NEXT: # %bb.11:
26;SJLJ-NEXT:         ud2
27;SJLJ-NEXT: .LBB0_10:
28;SJLJ-NEXT:         leaq    .LJTI0_0(%rip), %rcx
29;SJLJ-NEXT:         jmpq    *(%rcx,%rax,8)
30;SJLJ-NEXT: .LBB0_2:                                # %lpad
31;SJLJ-NEXT: .Ltmp2:
32;SJLJ-NEXT:         endbr64
33;SJLJ:               jne     .LBB0_4
34;SJLJ-NEXT: # %bb.3:                                # %catch3
35;SJLJ:               callq   __cxa_begin_catch
36;SJLJ:               jmp     .LBB0_6
37;SJLJ-NEXT: .LBB0_4:                                # %catch.fallthrough
38;SJLJ-NEXT:         cmpl
39;SJLJ-NEXT:         jne     .LBB0_8
40;SJLJ-NEXT: # %bb.5:                                # %catch
41;SJLJ:               callq   __cxa_begin_catch
42;SJLJ:               cmpb
43;SJLJ-NEXT: .LBB0_6:                                # %return
44;SJLJ:               callq   __cxa_end_catch
45;SJLJ-NEXT:         jmp     .LBB0_7
46;SJLJ-NEXT: .LBB0_8:                                # %eh.resume
47;SJLJ-NEXT:         movl
48;SJLJ-NEXT: .Lfunc_end0:
49;SJLJ:      .LJTI0_0:
50;SJLJ-NEXT:         .quad   .LBB0_2
51
52@_ZTIi = external dso_local constant i8*
53@_ZTIc = external dso_local constant i8*
54
55; Function Attrs: noinline norecurse optnone uwtable
56define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
57entry:
58  %retval = alloca i32, align 4
59  %exn.slot = alloca i8*
60  %ehselector.slot = alloca i32
61  %x = alloca i8, align 1
62  %x4 = alloca i32, align 4
63  store i32 0, i32* %retval, align 4
64  invoke void @_Z3foov()
65          to label %invoke.cont unwind label %lpad
66
67invoke.cont:                                      ; preds = %entry
68  br label %try.cont
69
70lpad:                                             ; preds = %entry
71  %0 = landingpad { i8*, i32 }
72          catch i8* bitcast (i8** @_ZTIi to i8*)
73          catch i8* bitcast (i8** @_ZTIc to i8*)
74  %1 = extractvalue { i8*, i32 } %0, 0
75  store i8* %1, i8** %exn.slot, align 8
76  %2 = extractvalue { i8*, i32 } %0, 1
77  store i32 %2, i32* %ehselector.slot, align 4
78  br label %catch.dispatch
79
80catch.dispatch:                                   ; preds = %lpad
81  %sel = load i32, i32* %ehselector.slot, align 4
82  %3 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3
83  %matches = icmp eq i32 %sel, %3
84  br i1 %matches, label %catch3, label %catch.fallthrough
85
86catch3:                                           ; preds = %catch.dispatch
87  %exn5 = load i8*, i8** %exn.slot, align 8
88  %4 = call i8* @__cxa_begin_catch(i8* %exn5) #3
89  %5 = bitcast i8* %4 to i32*
90  %6 = load i32, i32* %5, align 4
91  store i32 %6, i32* %x4, align 4
92  %7 = load i32, i32* %x4, align 4
93  %cmp6 = icmp ne i32 %7, 5
94  %conv7 = zext i1 %cmp6 to i32
95  store i32 %conv7, i32* %retval, align 4
96  call void @__cxa_end_catch() #3
97  br label %return
98
99catch.fallthrough:                                ; preds = %catch.dispatch
100  %8 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIc to i8*)) #3
101  %matches1 = icmp eq i32 %sel, %8
102  br i1 %matches1, label %catch, label %eh.resume
103
104catch:                                            ; preds = %catch.fallthrough
105  %exn = load i8*, i8** %exn.slot, align 8
106  %9 = call i8* @__cxa_begin_catch(i8* %exn) #3
107  %10 = load i8, i8* %9, align 1
108  store i8 %10, i8* %x, align 1
109  %11 = load i8, i8* %x, align 1
110  %conv = sext i8 %11 to i32
111  %cmp = icmp ne i32 %conv, 3
112  %conv2 = zext i1 %cmp to i32
113  store i32 %conv2, i32* %retval, align 4
114  call void @__cxa_end_catch() #3
115  br label %return
116
117try.cont:                                         ; preds = %invoke.cont
118  store i32 1, i32* %retval, align 4
119  br label %return
120
121return:                                           ; preds = %try.cont, %catch3, %catch
122  %12 = load i32, i32* %retval, align 4
123  ret i32 %12
124
125eh.resume:                                        ; preds = %catch.fallthrough
126  %exn8 = load i8*, i8** %exn.slot, align 8
127  %sel9 = load i32, i32* %ehselector.slot, align 4
128  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn8, 0
129  %lpad.val10 = insertvalue { i8*, i32 } %lpad.val, i32 %sel9, 1
130  resume { i8*, i32 } %lpad.val10
131}
132
133declare dso_local void @_Z3foov() #1
134
135declare dso_local i32 @__gxx_personality_sj0(...)
136
137; Function Attrs: nounwind readnone
138declare i32 @llvm.eh.typeid.for(i8*) #2
139
140declare dso_local i8* @__cxa_begin_catch(i8*)
141
142declare dso_local void @__cxa_end_catch()
143
144!llvm.module.flags = !{!0, !1, !2}
145
146!0 = !{i32 1, !"wchar_size", i32 4}
147!1 = !{i32 4, !"cf-protection-return", i32 1}
148!2 = !{i32 4, !"cf-protection-branch", i32 1}
149