[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Inline / deoptimize-intrinsic.ll
blob3d84bfc807691a94b3c413f69995ac97bcb1ecb8
1 ; RUN: opt -S -always-inline < %s | FileCheck %s
3 declare i8 @llvm.experimental.deoptimize.i8(...)
4 declare i32 @llvm.experimental.deoptimize.i32(...)
6 define i8 @callee(i1* %c) alwaysinline {
7   %c0 = load volatile i1, i1* %c
8   br i1 %c0, label %left, label %right
10 left:
11   %c1 = load volatile i1, i1* %c
12   br i1 %c1, label %lleft, label %lright
14 lleft:
15   %v0 = call i8(...) @llvm.experimental.deoptimize.i8(i32 1) [ "deopt"(i32 1) ]
16   ret i8 %v0
18 lright:
19   ret i8 10
21 right:
22   %c2 = load volatile i1, i1* %c
23   br i1 %c2, label %rleft, label %rright
25 rleft:
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
29 rright:
30   %v2 = call i8(...) @llvm.experimental.deoptimize.i8() [ "deopt"(i32 1) ]
31   ret i8 %v2
34 define void @caller_0(i1* %c, i8* %ptr) {
35 ; CHECK-LABEL: @caller_0(
36 entry:
37   %v = call i8 @callee(i1* %c)  [ "deopt"(i32 2) ]
38   store i8 %v, i8* %ptr
39   ret void
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
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
49 ; CHECK: rright.i:
50 ; CHECK-NEXT:  call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"(i32 2, i32 1) ]
51 ; CHECK-NEXT:  ret void
53 ; CHECK: callee.exit:
54 ; CHECK-NEXT:  store i8 10, i8* %ptr
55 ; CHECK-NEXT:  ret void
59 define i32 @caller_1(i1* %c, i8* %ptr) personality i8 3 {
60 ; CHECK-LABEL: @caller_1(
61 entry:
62   %v = invoke i8 @callee(i1* %c)  [ "deopt"(i32 3) ] to label %normal
63        unwind label %unwind
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
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
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
77 ; CHECK: callee.exit:
78 ; CHECK-NEXT:  br label %normal
80 ; CHECK: normal:
81 ; CHECK-NEXT:  store i8 10, i8* %ptr
82 ; CHECK-NEXT:  ret i32 42
84 unwind:
85   %lp = landingpad i32 cleanup
86   ret i32 43
88 normal:
89   store i8 %v, i8* %ptr
90   ret i32 42
93 define 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
99 define 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
104 entry:
105   call i8 @callee_with_alloca();
106   ret void
109 define 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
115 define 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
120   %p = alloca i32, i32 %n
121   call i8 @callee_with_dynamic_alloca(i32 %n)
122   ret void