Chandler Carruth | 67fc52f | 2016-08-17 02:56:20 +0000 | [diff] [blame] | 1 | ; RUN: opt < %s -inline-threshold=0 -always-inline -S | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 2 | ; |
| 3 | ; Ensure the threshold has no impact on these decisions. |
Chandler Carruth | 67fc52f | 2016-08-17 02:56:20 +0000 | [diff] [blame] | 4 | ; RUN: opt < %s -inline-threshold=20000000 -always-inline -S | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL |
| 5 | ; RUN: opt < %s -inline-threshold=-20000000 -always-inline -S | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CALL |
| 6 | ; |
| 7 | ; The new pass manager doesn't re-use any threshold based infrastructure for |
Chandler Carruth | f32f63f | 2016-12-23 23:33:32 +0000 | [diff] [blame] | 8 | ; the always inliner, but test that we get the correct result. The new PM |
| 9 | ; always inliner also doesn't support inlining call-site alwaysinline |
| 10 | ; annotations. It isn't clear that this is a reasonable use case for |
| 11 | ; 'alwaysinline'. |
| 12 | ; RUN: opt < %s -passes=always-inline -S | FileCheck %s --check-prefix=CHECK |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 13 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 14 | define internal i32 @inner1() alwaysinline { |
| 15 | ; CHECK-NOT: @inner1( |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 16 | ret i32 1 |
| 17 | } |
| 18 | define i32 @outer1() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 19 | ; CHECK-LABEL: @outer1( |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 20 | ; CHECK-NOT: call |
| 21 | ; CHECK: ret |
| 22 | |
| 23 | %r = call i32 @inner1() |
| 24 | ret i32 %r |
| 25 | } |
| 26 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 27 | ; The always inliner can't DCE arbitrary internal functions. PR2945 |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 28 | define internal i32 @pr2945() nounwind { |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 29 | ; CHECK-LABEL: @pr2945( |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 30 | ret i32 0 |
| 31 | } |
| 32 | |
| 33 | define internal void @inner2(i32 %N) alwaysinline { |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 34 | ; CHECK-NOT: @inner2( |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 35 | %P = alloca i32, i32 %N |
| 36 | ret void |
| 37 | } |
| 38 | define void @outer2(i32 %N) { |
| 39 | ; The always inliner (unlike the normal one) should be willing to inline |
| 40 | ; a function with a dynamic alloca into one without a dynamic alloca. |
| 41 | ; rdar://6655932 |
| 42 | ; |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 43 | ; CHECK-LABEL: @outer2( |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 44 | ; CHECK-NOT: call void @inner2 |
Chandler Carruth | 1989bb9 | 2012-04-01 10:11:17 +0000 | [diff] [blame] | 45 | ; CHECK-NOT: call void @inner2 |
| 46 | ; CHECK: ret void |
| 47 | |
| 48 | call void @inner2( i32 %N ) |
| 49 | ret void |
| 50 | } |
Chandler Carruth | c5bfb3c | 2012-04-01 10:21:05 +0000 | [diff] [blame] | 51 | |
| 52 | declare i32 @a() returns_twice |
| 53 | declare i32 @b() returns_twice |
| 54 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 55 | ; Cannot alwaysinline when that would introduce a returns_twice call. |
| 56 | define internal i32 @inner3() alwaysinline { |
| 57 | ; CHECK-LABEL: @inner3( |
Chandler Carruth | c5bfb3c | 2012-04-01 10:21:05 +0000 | [diff] [blame] | 58 | entry: |
| 59 | %call = call i32 @a() returns_twice |
| 60 | %add = add nsw i32 1, %call |
| 61 | ret i32 %add |
| 62 | } |
| 63 | define i32 @outer3() { |
| 64 | entry: |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 65 | ; CHECK-LABEL: @outer3( |
Chandler Carruth | c5bfb3c | 2012-04-01 10:21:05 +0000 | [diff] [blame] | 66 | ; CHECK-NOT: call i32 @a |
| 67 | ; CHECK: ret |
| 68 | |
| 69 | %call = call i32 @inner3() |
| 70 | %add = add nsw i32 1, %call |
| 71 | ret i32 %add |
| 72 | } |
| 73 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 74 | define internal i32 @inner4() alwaysinline returns_twice { |
| 75 | ; CHECK-NOT: @inner4( |
Chandler Carruth | c5bfb3c | 2012-04-01 10:21:05 +0000 | [diff] [blame] | 76 | entry: |
| 77 | %call = call i32 @b() returns_twice |
| 78 | %add = add nsw i32 1, %call |
| 79 | ret i32 %add |
| 80 | } |
| 81 | |
| 82 | define i32 @outer4() { |
| 83 | entry: |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 84 | ; CHECK-LABEL: @outer4( |
Chandler Carruth | c5bfb3c | 2012-04-01 10:21:05 +0000 | [diff] [blame] | 85 | ; CHECK: call i32 @b() |
| 86 | ; CHECK: ret |
| 87 | |
| 88 | %call = call i32 @inner4() returns_twice |
| 89 | %add = add nsw i32 1, %call |
| 90 | ret i32 %add |
| 91 | } |
Chandler Carruth | cdb1f8c | 2012-04-01 10:36:17 +0000 | [diff] [blame] | 92 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 93 | ; We can't inline this even though it has alwaysinline! |
| 94 | define internal i32 @inner5(i8* %addr) alwaysinline { |
| 95 | ; CHECK-LABEL: @inner5( |
Chandler Carruth | cdb1f8c | 2012-04-01 10:36:17 +0000 | [diff] [blame] | 96 | entry: |
| 97 | indirectbr i8* %addr, [ label %one, label %two ] |
| 98 | |
| 99 | one: |
| 100 | ret i32 42 |
| 101 | |
| 102 | two: |
| 103 | ret i32 44 |
| 104 | } |
| 105 | define i32 @outer5(i32 %x) { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 106 | ; CHECK-LABEL: @outer5( |
Chandler Carruth | cdb1f8c | 2012-04-01 10:36:17 +0000 | [diff] [blame] | 107 | ; CHECK: call i32 @inner5 |
| 108 | ; CHECK: ret |
| 109 | |
| 110 | %cmp = icmp slt i32 %x, 42 |
| 111 | %addr = select i1 %cmp, i8* blockaddress(@inner5, %one), i8* blockaddress(@inner5, %two) |
| 112 | %call = call i32 @inner5(i8* %addr) |
| 113 | ret i32 %call |
| 114 | } |
| 115 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 116 | ; We alwaysinline a function that call itself recursively. |
| 117 | define internal void @inner6(i32 %x) alwaysinline { |
| 118 | ; CHECK-LABEL: @inner6( |
Chandler Carruth | cdb1f8c | 2012-04-01 10:36:17 +0000 | [diff] [blame] | 119 | entry: |
| 120 | %icmp = icmp slt i32 %x, 0 |
| 121 | br i1 %icmp, label %return, label %bb |
| 122 | |
| 123 | bb: |
| 124 | %sub = sub nsw i32 %x, 1 |
| 125 | call void @inner6(i32 %sub) |
| 126 | ret void |
| 127 | |
| 128 | return: |
| 129 | ret void |
| 130 | } |
| 131 | define void @outer6() { |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 132 | ; CHECK-LABEL: @outer6( |
Chandler Carruth | cdb1f8c | 2012-04-01 10:36:17 +0000 | [diff] [blame] | 133 | ; CHECK: call void @inner6(i32 42) |
| 134 | ; CHECK: ret |
| 135 | |
| 136 | entry: |
| 137 | call void @inner6(i32 42) |
| 138 | ret void |
| 139 | } |
| 140 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 141 | ; This is not an alwaysinline function and is actually external. |
Peter Collingbourne | 68a8897 | 2014-05-19 18:25:54 +0000 | [diff] [blame] | 142 | define i32 @inner7() { |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 143 | ; CHECK-LABEL: @inner7( |
Peter Collingbourne | 68a8897 | 2014-05-19 18:25:54 +0000 | [diff] [blame] | 144 | ret i32 1 |
| 145 | } |
| 146 | define i32 @outer7() { |
Chandler Carruth | 67fc52f | 2016-08-17 02:56:20 +0000 | [diff] [blame] | 147 | ; CHECK-CALL-LABEL: @outer7( |
| 148 | ; CHECK-CALL-NOT: call |
| 149 | ; CHECK-CALL: ret |
Peter Collingbourne | 68a8897 | 2014-05-19 18:25:54 +0000 | [diff] [blame] | 150 | |
| 151 | %r = call i32 @inner7() alwaysinline |
| 152 | ret i32 %r |
| 153 | } |
Chandler Carruth | 67fc52f | 2016-08-17 02:56:20 +0000 | [diff] [blame] | 154 | |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 155 | define internal float* @inner8(float* nocapture align 128 %a) alwaysinline { |
| 156 | ; CHECK-NOT: @inner8( |
Chandler Carruth | 67fc52f | 2016-08-17 02:56:20 +0000 | [diff] [blame] | 157 | ret float* %a |
| 158 | } |
| 159 | define float @outer8(float* nocapture %a) { |
| 160 | ; CHECK-LABEL: @outer8( |
| 161 | ; CHECK-NOT: call float* @inner8 |
| 162 | ; CHECK: ret |
| 163 | |
| 164 | %inner_a = call float* @inner8(float* %a) |
| 165 | %f = load float, float* %inner_a, align 4 |
| 166 | ret float %f |
| 167 | } |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 168 | |
| 169 | |
| 170 | ; The 'inner9*' and 'outer9' functions are designed to check that we remove |
| 171 | ; a function that is inlined by the always inliner even when it is used by |
| 172 | ; a complex constant expression prior to being inlined. |
| 173 | |
| 174 | ; The 'a' function gets used in a complex constant expression that, despite |
| 175 | ; being constant folded, means it isn't dead. As a consequence it shouldn't be |
| 176 | ; deleted. If it is, then the constant expression needs to become more complex |
| 177 | ; to accurately test this scenario. |
| 178 | define internal void @inner9a(i1 %b) alwaysinline { |
| 179 | ; CHECK-LABEL: @inner9a( |
| 180 | entry: |
| 181 | ret void |
| 182 | } |
| 183 | |
| 184 | define internal void @inner9b(i1 %b) alwaysinline { |
| 185 | ; CHECK-NOT: @inner9b( |
| 186 | entry: |
| 187 | ret void |
| 188 | } |
| 189 | |
| 190 | declare void @dummy9(i1 %b) |
| 191 | |
| 192 | define void @outer9() { |
| 193 | ; CHECK-LABEL: @outer9( |
| 194 | entry: |
| 195 | ; First we use @inner9a in a complex constant expression that may get folded |
| 196 | ; but won't get removed, and then we call it which will get inlined. Despite |
| 197 | ; this the function can't be deleted because of the constant expression |
| 198 | ; usage. |
| 199 | %sink = alloca i1 |
| 200 | store volatile i1 icmp eq (i64 ptrtoint (void (i1)* @inner9a to i64), i64 ptrtoint(void (i1)* @dummy9 to i64)), i1* %sink |
| 201 | ; CHECK: store volatile |
| 202 | call void @inner9a(i1 false) |
| 203 | ; CHECK-NOT: call void @inner9a |
| 204 | |
| 205 | ; Next we call @inner9b passing in a constant expression. This constant |
| 206 | ; expression will in fact be removed by inlining, so we should also be able |
| 207 | ; to delete the function. |
| 208 | call void @inner9b(i1 icmp eq (i64 ptrtoint (void (i1)* @inner9b to i64), i64 ptrtoint(void (i1)* @dummy9 to i64))) |
| 209 | ; CHECK-NOT: @inner9b |
| 210 | |
| 211 | ret void |
| 212 | ; CHECK: ret void |
| 213 | } |
| 214 | |
| 215 | ; The 'inner10' and 'outer10' functions test a frustrating consquence of the |
| 216 | ; current 'alwaysinline' semantic model. Because such functions are allowed to |
| 217 | ; be external functions, it may be necessary to both inline all of their uses |
| 218 | ; and leave them in the final output. These tests can be removed if and when |
| 219 | ; we restrict alwaysinline further. |
| 220 | define void @inner10() alwaysinline { |
| 221 | ; CHECK-LABEL: @inner10( |
| 222 | entry: |
| 223 | ret void |
| 224 | } |
| 225 | |
| 226 | define void @outer10() { |
| 227 | ; CHECK-LABEL: @outer10( |
| 228 | entry: |
| 229 | call void @inner10() |
| 230 | ; CHECK-NOT: call void @inner10 |
| 231 | |
| 232 | ret void |
| 233 | ; CHECK: ret void |
| 234 | } |
| 235 | |
| 236 | ; The 'inner11' and 'outer11' functions test another dimension of non-internal |
| 237 | ; functions with alwaysinline. These functions use external linkages that we can |
| 238 | ; actually remove safely and so we should. |
| 239 | define linkonce void @inner11a() alwaysinline { |
| 240 | ; CHECK-NOT: @inner11a( |
| 241 | entry: |
| 242 | ret void |
| 243 | } |
| 244 | |
| 245 | define available_externally void @inner11b() alwaysinline { |
| 246 | ; CHECK-NOT: @inner11b( |
| 247 | entry: |
| 248 | ret void |
| 249 | } |
| 250 | |
| 251 | define void @outer11() { |
| 252 | ; CHECK-LABEL: @outer11( |
| 253 | entry: |
| 254 | call void @inner11a() |
| 255 | call void @inner11b() |
| 256 | ; CHECK-NOT: call void @inner11a |
| 257 | ; CHECK-NOT: call void @inner11b |
| 258 | |
| 259 | ret void |
| 260 | ; CHECK: ret void |
| 261 | } |
| 262 | |
| 263 | ; The 'inner12' and 'outer12' functions test that we don't remove functions |
| 264 | ; which are part of a comdat group even if they otherwise seem dead. |
| 265 | $comdat12 = comdat any |
| 266 | |
| 267 | define linkonce void @inner12() alwaysinline comdat($comdat12) { |
| 268 | ; CHECK-LABEL: @inner12( |
Chandler Carruth | 4eaff12 | 2016-12-23 23:33:35 +0000 | [diff] [blame] | 269 | ret void |
| 270 | } |
| 271 | |
| 272 | define void @outer12() comdat($comdat12) { |
| 273 | ; CHECK-LABEL: @outer12( |
| 274 | entry: |
| 275 | call void @inner12() |
| 276 | ; CHECK-NOT: call void @inner12 |
| 277 | |
| 278 | ret void |
| 279 | ; CHECK: ret void |
| 280 | } |
Chandler Carruth | 6e9bb7e | 2016-12-26 23:43:27 +0000 | [diff] [blame] | 281 | |
| 282 | ; The 'inner13*' and 'outer13' functions test that we do remove functions |
| 283 | ; which are part of a comdat group where all of the members are removed during |
| 284 | ; always inlining. |
| 285 | $comdat13 = comdat any |
| 286 | |
| 287 | define linkonce void @inner13a() alwaysinline comdat($comdat13) { |
| 288 | ; CHECK-NOT: @inner13a( |
| 289 | ret void |
| 290 | } |
| 291 | |
| 292 | define linkonce void @inner13b() alwaysinline comdat($comdat13) { |
| 293 | ; CHECK-NOT: @inner13b( |
| 294 | ret void |
| 295 | } |
| 296 | |
| 297 | define void @outer13() { |
| 298 | ; CHECK-LABEL: @outer13( |
| 299 | entry: |
| 300 | call void @inner13a() |
| 301 | call void @inner13b() |
| 302 | ; CHECK-NOT: call void @inner13a |
| 303 | ; CHECK-NOT: call void @inner13b |
| 304 | |
| 305 | ret void |
| 306 | ; CHECK: ret void |
| 307 | } |
David Blaikie | ae8c4af | 2017-06-12 23:01:17 +0000 | [diff] [blame] | 308 | |
| 309 | define void @inner14() readnone nounwind { |
| 310 | ; CHECK: define void @inner14 |
| 311 | ret void |
| 312 | } |
| 313 | |
| 314 | define void @outer14() { |
| 315 | ; CHECK: call void @inner14 |
| 316 | call void @inner14() |
| 317 | ret void |
| 318 | } |