1; RUN: llc -O0 -mtriple=aarch64-apple-ios -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
2
3@_ZTIi = external global i8*
4
5declare i32 @foo(i32)
6declare i32 @__gxx_personality_v0(...)
7declare i32 @llvm.eh.typeid.for(i8*)
8
9; CHECK-LABEL: name: bar
10; CHECK: body:
11; CHECK-NEXT:   bb.1 (%ir-block.0):
12; CHECK:     successors: %[[GOOD:bb.[0-9]+]]{{.*}}%[[BAD:bb.[0-9]+]]
13; CHECK:     EH_LABEL
14; CHECK:     $w0 = COPY
15; CHECK:     BL @foo, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0, implicit-def $w0
16; CHECK:     {{%[0-9]+}}:_(s32) = COPY $w0
17; CHECK:     EH_LABEL
18; CHECK:     G_BR %[[GOOD]]
19
20; CHECK:   [[BAD]].{{[a-z]+}} (landing-pad):
21; CHECK:     EH_LABEL
22; CHECK:     [[PTR_RET:%[0-9]+]]:_(p0) = COPY $x0
23; CHECK:     [[SEL_PTR:%[0-9]+]]:_(p0) = COPY $x1
24; CHECK:     [[SEL_RET:%[0-9]+]]:_(s32) = G_PTRTOINT [[SEL_PTR]]
25; CHECK:     $x0 = COPY [[PTR_RET]]
26; CHECK:     $w1 = COPY [[SEL_RET]]
27
28; CHECK:   [[GOOD]].{{[a-z]+}}:
29; CHECK:     [[SEL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
30; CHECK:     $w1 = COPY [[SEL]]
31
32define { i8*, i32 } @bar() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
33  %res32 = invoke i32 @foo(i32 42) to label %continue unwind label %broken
34
35
36broken:
37  %ptr.sel = landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
38  ret { i8*, i32 } %ptr.sel
39
40continue:
41  %sel.int = tail call i32 @llvm.eh.typeid.for(i8* bitcast(i8** @_ZTIi to i8*))
42  %res.good = insertvalue { i8*, i32 } undef, i32 %sel.int, 1
43  ret { i8*, i32 } %res.good
44}
45
46; CHECK-LABEL: name: test_invoke_indirect
47; CHECK: [[CALLEE:%[0-9]+]]:gpr64(p0) = COPY $x0
48; CHECK: BLR [[CALLEE]]
49define void @test_invoke_indirect(void()* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
50  invoke void %callee() to label %continue unwind label %broken
51
52broken:
53  landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
54  ret void
55
56continue:
57  ret void
58}
59
60; CHECK-LABEL: name: test_invoke_varargs
61
62; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
63; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
64; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.0
65
66; CHECK: $x0 = COPY [[NULL]]
67
68; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp
69; CHECK: [[OFFSET:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
70; CHECK: [[SLOT:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFFSET]](s64)
71; CHECK: [[ANSWER_EXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ANSWER]]
72; CHECK: G_STORE [[ANSWER_EXT]](s64), [[SLOT]]
73
74; CHECK: [[OFFSET:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
75; CHECK: [[SLOT:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFFSET]](s64)
76; CHECK: G_STORE [[ONE]](s32), [[SLOT]]
77
78; CHECK: BL @printf
79declare void @printf(i8*, ...)
80define void @test_invoke_varargs() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
81  invoke void(i8*, ...) @printf(i8* null, i32 42, float 1.0) to label %continue unwind label %broken
82
83broken:
84  landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
85  ret void
86
87continue:
88  ret void
89}
90
91; CHECK-LABEL: name: test_lpad_phi
92; CHECK: body:
93; CHECK-NEXT:   bb.1 (%ir-block.0):
94; CHECK:     successors: %[[GOOD:bb.[0-9]+]]{{.*}}%[[BAD:bb.[0-9]+]]
95; CHECK:     [[ELEVEN:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
96; CHECK:     EH_LABEL
97; CHECK:     BL @may_throw, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp
98; CHECK:     EH_LABEL
99; CHECK:     G_BR %[[GOOD]]
100
101; CHECK:   [[BAD]].{{[a-z]+}} (landing-pad):
102; CHECK:     [[PHI_ELEVEN:%[0-9]+]]:_(s32) = G_PHI [[ELEVEN]](s32), %bb.1
103; CHECK:     EH_LABEL
104; CHECK:     G_STORE [[PHI_ELEVEN]](s32), {{%[0-9]+}}(p0) :: (store 4 into @global_var)
105
106; CHECK:   [[GOOD]].{{[a-z]+}}:
107; CHECK:     [[SEL:%[0-9]+]]:_(s32) = G_PHI
108; CHECK:     $w0 = COPY [[SEL]]
109
110@global_var = external global i32
111
112declare void @may_throw()
113define i32 @test_lpad_phi() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
114  store i32 42, i32* @global_var
115  invoke void @may_throw()
116          to label %continue unwind label %lpad
117
118lpad:                                             ; preds = %entry
119  %p = phi i32 [ 11, %0 ]  ; Trivial, but -O0 keeps it
120  %1 = landingpad { i8*, i32 }
121          catch i8* null
122  store i32 %p, i32* @global_var
123  br label %continue
124
125continue:                                         ; preds = %entry, %lpad
126  %r.0 = phi i32 [ 13, %0 ], [ 55, %lpad ]
127  ret i32 %r.0
128}
129