@@ -14,6 +14,8 @@ struct Bool {
14
14
15
15
protocol Error {}
16
16
17
+ class C {}
18
+
17
19
// CHECK-LABEL: sil @simple_promotion
18
20
sil @simple_promotion : $(Int) -> Int {
19
21
bb0(%0 : $Int):
901
903
// CHECK: bb1:
902
904
// CHECK-NEXT: [[STACK2:%[0-9]+]] = alloc_stack $Bool
903
905
// CHECK-NEXT: dealloc_stack [[STACK2]]
904
- // CHECK-NEXT: dealloc_stack [[BOX]]
905
906
// CHECK-NEXT: unreachable
906
907
// CHECK: bb2:
907
908
// CHECK: store {{%[0-9]+}}
@@ -1059,10 +1060,8 @@ bb3:
1059
1060
// CHECK-NEXT: [[AI:%[0-9]+]] = alloc_stack $Int
1060
1061
// CHECK-NEXT: cond_br
1061
1062
// CHECK: bb1:
1062
- // CHECK-NEXT: dealloc_stack [[AI]]
1063
1063
// CHECK-NEXT: br bb3
1064
1064
// CHECK: bb2:
1065
- // CHECK-NEXT: dealloc_stack [[AI]]
1066
1065
// CHECK-NEXT: br bb3
1067
1066
// CHECK: bb3:
1068
1067
// CHECK-NEXT: store {{%[0-9]+}}
@@ -1226,3 +1225,201 @@ bb0:
1226
1225
destroy_value %box : ${ var Builtin.Int32 }
1227
1226
return %value : $Builtin.Int32
1228
1227
}
1228
+
1229
+ sil @getC : $@convention(thin) () -> (@owned C)
1230
+
1231
+ // CHECK-LABEL: sil @leak_to_inf_loop_1 : {{.*}} {
1232
+ // CHECK-NOT: destroy_addr
1233
+ // CHECK-NOT: dealloc_stack
1234
+ // CHECK-LABEL: } // end sil function 'leak_to_inf_loop_1'
1235
+ sil @leak_to_inf_loop_1 : $@convention(thin) (@owned C) -> () {
1236
+ entry(%c : $C):
1237
+ %box = alloc_box ${ var C }
1238
+ %c_addr = project_box %box, 0
1239
+ store %c to %c_addr
1240
+ strong_retain %box
1241
+ strong_release %box
1242
+ br loop
1243
+
1244
+ loop:
1245
+ %getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1246
+ %c2 = apply %getC() : $@convention(thin) () -> (@owned C)
1247
+ %c_old = load %c_addr
1248
+ store %c2 to %c_addr
1249
+ release_value %c_old
1250
+ br loop
1251
+ }
1252
+
1253
+ // CHECK-LABEL: sil @leak_to_inf_loop_2 : {{.*}} {
1254
+ // CHECK: cond_br undef, [[EXIT:bb[0-9]+]], [[TO_LOOP:bb[0-9]+]]
1255
+ // CHECK: [[EXIT]]
1256
+ // CHECK: destroy_addr
1257
+ // CHECK: dealloc_stack
1258
+ // CHECK: [[TO_LOOP]]
1259
+ // CHECK-NOT: destroy_addr
1260
+ // CHECK-NOT: dealloc_stack
1261
+ // CHECK-LABEL: } // end sil function 'leak_to_inf_loop_2'
1262
+ sil @leak_to_inf_loop_2 : $@convention(thin) (@owned C) -> () {
1263
+ entry(%c : $C):
1264
+ %box = alloc_box ${ var C }
1265
+ %c_addr = project_box %box, 0
1266
+ store %c to %c_addr
1267
+ strong_retain %box
1268
+ strong_release %box
1269
+ cond_br undef, exit, to_loop
1270
+
1271
+ exit:
1272
+ strong_release %box
1273
+ return undef : $()
1274
+
1275
+ to_loop:
1276
+ strong_retain %box
1277
+ strong_release %box
1278
+ br loop
1279
+
1280
+ loop:
1281
+ %getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1282
+ %c2 = apply %getC() : $@convention(thin) () -> (@owned C)
1283
+ %c_old = load %c_addr
1284
+ store %c2 to %c_addr
1285
+ release_value %c_old
1286
+ br loop
1287
+ }
1288
+
1289
+ // CHECK-LABEL: sil @leak_to_inf_loop_3 : {{.*}} {
1290
+ // CHECK-NOT: destroy_addr
1291
+ // CHECK-NOT: dealloc_stack
1292
+ // CHECK-LABEL: } // end sil function 'leak_to_inf_loop_3'
1293
+ sil @leak_to_inf_loop_3 : $@convention(thin) (@owned C) -> () {
1294
+ entry(%c : $C):
1295
+ %box = alloc_box ${ var C }
1296
+ %c_addr = project_box %box, 0
1297
+ store %c to %c_addr
1298
+ br to_loop
1299
+
1300
+ to_loop:
1301
+ strong_retain %box
1302
+ strong_release %box
1303
+ br loop
1304
+
1305
+ loop:
1306
+ %getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1307
+ %c2 = apply %getC() : $@convention(thin) () -> (@owned C)
1308
+ %c_old = load %c_addr
1309
+ store %c2 to %c_addr
1310
+ release_value %c_old
1311
+ br loop
1312
+ }
1313
+
1314
+ // CHECK-LABEL: sil @dealloc_box_before_loop
1315
+ // CHECK: dealloc_stack
1316
+ // CHECK-LABEL: } // end sil function 'dealloc_box_before_loop'
1317
+ sil @dealloc_box_before_loop : $@convention(thin) (@owned C) -> () {
1318
+ entry(%c : $C):
1319
+ %box = alloc_box ${ var C }
1320
+ %c_addr = project_box %box, 0
1321
+ store %c to %c_addr
1322
+ cond_br undef, exit, to_loop
1323
+
1324
+ exit:
1325
+ strong_release %box
1326
+ return undef : $()
1327
+
1328
+ to_loop:
1329
+ dealloc_box %box
1330
+ br loop
1331
+
1332
+ loop:
1333
+ br loop
1334
+ }
1335
+
1336
+ // CHECK-LABEL: sil @alloc_box_in_deadend_loop
1337
+ // CHECK: alloc_stack
1338
+ // CHECK: dealloc_stack
1339
+ // CHECK-LABEL: } // end sil function 'alloc_box_in_deadend_loop'
1340
+ sil @alloc_box_in_deadend_loop : $@convention(thin) () -> () {
1341
+ entry:
1342
+ br loop
1343
+
1344
+ loop:
1345
+ %box = alloc_box ${ var C }
1346
+ %c_addr = project_box %box, 0
1347
+ %getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1348
+ %c = apply %getC() : $@convention(thin) () -> (@owned C)
1349
+ store %c to %c_addr
1350
+ strong_release %box
1351
+ br loop
1352
+ }
1353
+
1354
+ // CHECK-LABEL: sil @alloc_box_in_exiting_loop
1355
+ // CHECK: br [[EXITING_LOOP:bb[0-9]+]]
1356
+ // CHECK: [[EXITING_LOOP]]:
1357
+ // CHECK: alloc_stack
1358
+ // CHECK: cond_br undef, [[EXIT:bb[0-9]+]], [[LATCH:bb[0-9]+]]
1359
+ // CHECK: [[LATCH]]:
1360
+ // CHECK: cond_br undef, [[BACKEDGE:bb[0-9]+]], [[INFINITE_LOOP:bb[0-9]+]]
1361
+ // CHECK: [[BACKEDGE]]:
1362
+ // CHECK: dealloc_stack
1363
+ // CHECK: br [[EXITING_LOOP]]
1364
+ // CHECK: [[EXIT]]:
1365
+ // CHECK: dealloc_stack
1366
+ // CHECK: [[INFINITE_LOOP]]:
1367
+ // CHECK-NOT: dealloc_stack
1368
+ // CHECK-LABEL: } // end sil function 'alloc_box_in_exiting_loop'
1369
+ sil @alloc_box_in_exiting_loop : $@convention(thin) () -> () {
1370
+ entry:
1371
+ br exiting_loop
1372
+
1373
+ exiting_loop:
1374
+ %box = alloc_box ${ var C }
1375
+ %c_addr = project_box %box, 0
1376
+ cond_br undef, exit, latch
1377
+
1378
+ latch:
1379
+ cond_br undef, backedge, infinite_loop
1380
+
1381
+ backedge:
1382
+ strong_release %box
1383
+ br exiting_loop
1384
+
1385
+ exit:
1386
+ strong_release %box
1387
+ return undef : $()
1388
+
1389
+ infinite_loop:
1390
+ %getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1391
+ %c = apply %getC() : $@convention(thin) () -> (@owned C)
1392
+ store %c to %c_addr
1393
+ strong_retain %box
1394
+ strong_release %box
1395
+ br infinite_loop
1396
+ }
1397
+
1398
+ // CHECK-LABEL: sil @alloc_box_in_deadend_loop_with_another_deadend
1399
+ // CHECK: br [[LOOP:bb[0-9]+]]
1400
+ // CHECK: [[LOOP]]:
1401
+ // CHECK: alloc_stack
1402
+ // CHECK: cond_br undef, [[BACKEDGE:bb[0-9]+]], [[DIE:bb[0-9]+]]
1403
+ // CHECK: [[BACKEDGE]]:
1404
+ // CHECK: dealloc_stack
1405
+ // CHECK: br [[LOOP]]
1406
+ // CHECK: [[DIE]]:
1407
+ // CHECK-NOT: dealloc_stack
1408
+ // CHECK-LABEL: } // end sil function 'alloc_box_in_deadend_loop_with_another_deadend'
1409
+ sil @alloc_box_in_deadend_loop_with_another_deadend : $@convention(thin) () -> () {
1410
+ entry:
1411
+ br loop
1412
+
1413
+ loop:
1414
+ %box = alloc_box ${ var C }
1415
+ cond_br undef, backedge, die
1416
+
1417
+ backedge:
1418
+ strong_release %box
1419
+ br loop
1420
+
1421
+ die:
1422
+ strong_retain %box
1423
+ strong_release %box
1424
+ unreachable
1425
+ }
0 commit comments