• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -S -always-inline < %s | FileCheck %s
2
3declare i8 @llvm.experimental.deoptimize.i8(...)
4declare i32 @llvm.experimental.deoptimize.i32(...)
5
6define i8 @callee(i1* %c) alwaysinline {
7  %c0 = load volatile i1, i1* %c
8  br i1 %c0, label %left, label %right
9
10left:
11  %c1 = load volatile i1, i1* %c
12  br i1 %c1, label %lleft, label %lright
13
14lleft:
15  %v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
16  ret i8 %v0
17
18lright:
19  ret i8 10
20
21right:
22  %c2 = load volatile i1, i1* %c
23  br i1 %c2, label %rleft, label %rright
24
25rleft:
26  %v1 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1, i32 300, float 500.0, <2 x i32*> undef) [ "deopt"(i32 1) ]
27  ret i8 %v1
28
29rright:
30  %v2 = call i8(...) @llvm.experimental.deoptimize.i8() [ "deopt"(i32 1) ]
31  ret i8 %v2
32}
33
34define void @caller_0(i1* %c, i8* %ptr) {
35; CHECK-LABEL: @caller_0(
36entry:
37  %v = call i8 @callee(i1* %c)  [ "deopt"(i32 2) ]
38  store i8 %v, i8* %ptr
39  ret void
40
41; CHECK: lleft.i:
42; CHECK-NEXT:  call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i32 2, i32 1) ]
43; CHECK-NEXT:  ret void
44
45; CHECK: rleft.i:
46; CHECK-NEXT:  call void (...) @llvm.experimental.deoptimize.isVoid(i32 1, i32 300, float 5.000000e+02, <2 x i32*> undef) [ "deopt"(i32 2, i32 1) ]
47; CHECK-NEXT:  ret void
48
49; CHECK: rright.i:
50; CHECK-NEXT:  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 2, i32 1) ]
51; CHECK-NEXT:  ret void
52
53; CHECK: callee.exit:
54; CHECK-NEXT:  store i8 10, i8* %ptr
55; CHECK-NEXT:  ret void
56
57}
58
59define i32 @caller_1(i1* %c, i8* %ptr) personality i8 3 {
60; CHECK-LABEL: @caller_1(
61entry:
62  %v = invoke i8 @callee(i1* %c)  [ "deopt"(i32 3) ] to label %normal
63       unwind label %unwind
64
65; CHECK: lleft.i:
66; CHECK-NEXT:  %0 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 1) [ "deopt"(i32 3, i32 1) ]
67; CHECK-NEXT:  ret i32 %0
68
69; CHECK: rleft.i:
70; CHECK-NEXT:  %1 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 1, i32 300, float 5.000000e+02, <2 x i32*> undef) [ "deopt"(i32 3, i32 1) ]
71; CHECK-NEXT:  ret i32 %1
72
73; CHECK: rright.i:
74; CHECK-NEXT:  %2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 3, i32 1) ]
75; CHECK-NEXT:  ret i32 %2
76
77; CHECK: callee.exit:
78; CHECK-NEXT:  br label %normal
79
80; CHECK: normal:
81; CHECK-NEXT:  store i8 10, i8* %ptr
82; CHECK-NEXT:  ret i32 42
83
84unwind:
85  %lp = landingpad i32 cleanup
86  ret i32 43
87
88normal:
89  store i8 %v, i8* %ptr
90  ret i32 42
91}
92
93define i8 @callee_with_alloca() alwaysinline {
94  %t = alloca i8
95  %v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i8* %t) ]
96  ret i8 %v0
97}
98
99define void @caller_with_lifetime() {
100; CHECK-LABEL: @caller_with_lifetime(
101; CHECK:  call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i8* %t.i) ]
102; CHECK-NEXT:  ret void
103
104entry:
105  call i8 @callee_with_alloca();
106  ret void
107}
108
109define i8 @callee_with_dynamic_alloca(i32 %n) alwaysinline {
110  %p = alloca i8, i32 %n
111  %v = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i8* %p) ]
112  ret i8 %v
113}
114
115define void @caller_with_stacksaverestore(i32 %n) {
116; CHECK-LABEL: void @caller_with_stacksaverestore(
117; CHECK:  call void (...) @llvm.experimental.deoptimize.isVoid(i32 1) [ "deopt"(i8* %p.i) ]
118; CHECK-NEXT:  ret void
119
120  %p = alloca i32, i32 %n
121  call i8 @callee_with_dynamic_alloca(i32 %n)
122  ret void
123}
124