[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Inline / deopt-bundles.ll
blob3e3c52f7d2d5988819653bb9204fdefb325403a8
1 ; RUN: opt -S -always-inline < %s | FileCheck %s
3 declare void @f()
4 declare i32 @g()
5 declare fastcc i32 @g.fastcc()
7 define i32 @callee_0() alwaysinline {
8  entry:
9   call void @f()
10   ret i32 2
13 define i32 @caller_0() {
14 ; CHECK-LABEL: @caller_0(
15  entry:
16 ; CHECK: entry:
17 ; CHECK-NEXT: call void @f()
18 ; CHECK-NEXT: ret i32 2
19   %x = call i32 @callee_0() [ "deopt"(i32 5) ]
20   ret i32 %x
23 define i32 @callee_1() alwaysinline {
24  entry:
25   call void @f() [ "deopt"() ]
26   call void @f() [ "deopt"(i32 0, i32 1) ]
27   call void @f() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
28   ret i32 2
31 define i32 @caller_1() {
32 ; CHECK-LABEL: @caller_1(
33  entry:
34 ; CHECK: entry:
35 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5) ]
36 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1) ]
37 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1), "foo"(double 0.000000e+00) ]
38 ; CHECK-NEXT:  ret i32 2
40   %x = call i32 @callee_1() [ "deopt"(i32 5) ]
41   ret i32 %x
44 define i32 @callee_2() alwaysinline {
45  entry:
46   %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
47   ret i32 %v
50 define i32 @caller_2(i32 %val) {
51 ; CHECK-LABEL: @caller_2(
52  entry:
53 ; CHECK: entry:
54 ; CHECK-NEXT:   [[RVAL:%[^ ]+]] = call i32 @g() [ "deopt"(i32 %val, i32 0, i32 1), "foo"(double 0.000000e+00) ]
55 ; CHECK-NEXT:   ret i32 [[RVAL]]
56   %x = call i32 @callee_2() [ "deopt"(i32 %val) ]
57   ret i32 %x
60 define i32 @callee_3() alwaysinline {
61  entry:
62   %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
63   ret i32 %v
66 define i32 @caller_3() personality i8 3 {
67 ; CHECK-LABEL: @caller_3(
68  entry:
69   %x = invoke i32 @callee_3() [ "deopt"(i32 7) ] to label %normal unwind label %unwind
70 ; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
72  normal:
73   ret i32 %x
75  unwind:
76   %cleanup = landingpad i8 cleanup
77   ret i32 101
80 define i32 @callee_4() alwaysinline personality i8 3 {
81  entry:
82   %v = invoke i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
84  normal:
85   ret i32 %v
87  unwind:
88   %cleanup = landingpad i8 cleanup
89   ret i32 100
92 define i32 @caller_4() {
93 ; CHECK-LABEL: @caller_4(
94  entry:
95 ; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
96   %x = call i32 @callee_4() [ "deopt"(i32 7) ]
97   ret i32 %x
100 define i32 @callee_5() alwaysinline personality i8 3 {
101  entry:
102   %v = invoke fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
104  normal:
105   ret i32 %v
107  unwind:
108   %cleanup = landingpad i8 cleanup
109   ret i32 100
112 define i32 @caller_5() {
113 ; CHECK-LABEL: @caller_5(
114  entry:
115 ; CHECK:  invoke fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX:[0-9]+]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
116   %x = call i32 @callee_5() [ "deopt"(i32 7) ]
117   ret i32 %x
120 define i32 @callee_6() alwaysinline personality i8 3 {
121  entry:
122   %v = call fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
123   ret i32 %v
126 define i32 @caller_6() {
127 ; CHECK-LABEL: @caller_6(
128  entry:
129 ; CHECK: call fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
130   %x = call i32 @callee_6() [ "deopt"(i32 7) ]
131   ret i32 %x
134 define i32 @callee_7(i1 %val) alwaysinline personality i8 3 {
135 ; We want something that PruningFunctionCloner is not smart enough to
136 ; recognize, but can be recognized by recursivelySimplifyInstruction.
138  entry:
139   br i1 %val, label %check, label %precheck
141  precheck:
142   br label %check
144  check:
145   %p = phi i1 [ %val, %entry ], [ true, %precheck ]
146   br i1 %p, label %do.not, label %do
148  do.not:
149   ret i32 0
151  do:
152   %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
153   ret i32 %v
156 define i32 @caller_7() {
157 ; CHECK-LABEL: @caller_7(
158  entry:
159 ; CHECK-NOT: call fastcc i32 @g.fastcc()
160 ; CHECK: ret i32 0
161   %x = call i32 @callee_7(i1 true) [ "deopt"(i32 7) ]
162   ret i32 %x
165 define i32 @callee_8(i1 %val) alwaysinline personality i8 3 {
166 ; We want something that PruningFunctionCloner is not smart enough to
167 ; recognize, but can be recognized by recursivelySimplifyInstruction.
169  entry:
170   br i1 %val, label %check, label %precheck
172  precheck:
173   br label %check
175  check:
176   %p = phi i1 [ %val, %entry ], [ true, %precheck ]
177   br i1 %p, label %do.not, label %do
179  do.not:
180   ret i32 0
182  do:
183   %phi = phi i32 [ 0, %check ], [ %v, %do ]
184   %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
185   %ic = icmp eq i32 %v, 42
186   br i1 %ic, label %do, label %done
188  done:
189   ret i32 %phi
192 define i32 @caller_8() {
193 ; CHECK-LABEL: @caller_8(
194  entry:
195 ; CHECK-NOT: call fastcc i32 @g.fastcc()
196 ; CHECK: ret i32 0
197   %x = call i32 @callee_8(i1 true) [ "deopt"(i32 7) ]
198   ret i32 %x
201 attributes #0 = { "foo"="bar" }
203 ; CHECK: attributes #[[FOO_BAR_ATTR_IDX]] = { "foo"="bar" }