@@ -8,6 +8,13 @@ sil_stage canonical
8
8
import Builtin
9
9
import Swift
10
10
11
+ class Storage {
12
+ init()
13
+ }
14
+
15
+ // globalArray
16
+ sil_global @globalArray : $Storage
17
+
11
18
// CHECK-LABEL: @memset
12
19
13
20
// CHECK: bb0
@@ -1397,3 +1404,71 @@ bb6:
1397
1404
return %15 : $()
1398
1405
}
1399
1406
1407
+ struct UInt64 {
1408
+ @_hasStorage var _value: Builtin.Int64 { get set }
1409
+ init(_value: Builtin.Int64)
1410
+ }
1411
+
1412
+ public struct UInt64Wrapper {
1413
+ @_hasStorage public var rawValue: UInt64 { get set }
1414
+ private init(_ rawValue: UInt64)
1415
+ public init()
1416
+ }
1417
+
1418
+ // rdar://92191909 (LICM assertion: isSubObjectProjection(), MemAccessUtils.h, line 1069)
1419
+ //
1420
+ // projectLoadValue needs to rematerialize a loaded value within the
1421
+ // loop using projections and the loop-invariant address is an
1422
+ // index_addr.
1423
+ //
1424
+ // The store inside the loop is deleted, and the load is hoisted such
1425
+ // that it now loads the UInt64Wrapper instead of Builtin.Int64
1426
+ // CHECK-LABEL: sil @testTailProjection : $@convention(thin) () -> () {
1427
+ // CHECK: bb0:
1428
+ // CHECK: [[A:%.*]] = index_addr %4 : $*UInt64Wrapper, %1 : $Builtin.Word
1429
+ // CHECK: store %{{.*}} to [[A]] : $*UInt64Wrapper
1430
+ // CHECK: load %5 : $*UInt64Wrapper
1431
+ // CHECK: br bb1
1432
+ // CHECK: bb1(%{{.*}} : $Builtin.Int64, %{{.*}} : $UInt64Wrapper, [[PHI:%.*]] : $UInt64Wrapper):
1433
+ // CHECK: cond_br undef, bb3, bb2
1434
+ // CHECK: bb2:
1435
+ // CHECK-NOT: (load|store)
1436
+ // CHECK: struct_extract [[PHI]] : $UInt64Wrapper, #UInt64Wrapper.rawValue
1437
+ // CHECK: struct_extract
1438
+ // CHECK: struct $UInt64
1439
+ // CHECK: struct $UInt64Wrapper
1440
+ // CHECK-NOT: (load|store)
1441
+ // CHECK: br bb1
1442
+ // CHECK: bb3:
1443
+ // CHECK: store [[PHI]] to [[A]] : $*UInt64Wrapper
1444
+ // CHECK-LABEL: } // end sil function 'testTailProjection'
1445
+ sil @testTailProjection : $@convention(thin) () -> () {
1446
+ bb0:
1447
+ %0 = integer_literal $Builtin.Int64, 0
1448
+ %1 = integer_literal $Builtin.Word, 1
1449
+ %2 = integer_literal $Builtin.Word, 2
1450
+ %3 = alloc_ref [tail_elems $UInt64Wrapper * %2 : $Builtin.Word] $Storage
1451
+ %4 = ref_tail_addr %3 : $Storage, $UInt64Wrapper
1452
+ %5 = index_addr %4 : $*UInt64Wrapper, %1 : $Builtin.Word
1453
+ %6 = struct $UInt64 (%0 : $Builtin.Int64)
1454
+ %7 = struct $UInt64Wrapper (%6 : $UInt64)
1455
+ store %7 to %5 : $*UInt64Wrapper
1456
+ %9 = load %5 : $*UInt64Wrapper
1457
+ br bb1(%0 : $Builtin.Int64, %9 : $UInt64Wrapper)
1458
+
1459
+ bb1(%11 : $Builtin.Int64, %12 : $UInt64Wrapper):
1460
+ cond_br undef, bb3, bb2
1461
+
1462
+ bb2:
1463
+ %14 = struct_element_addr %5 : $*UInt64Wrapper, #UInt64Wrapper.rawValue
1464
+ %15 = struct_element_addr %14 : $*UInt64, #UInt64._value
1465
+ %16 = load %15 : $*Builtin.Int64
1466
+ %17 = struct $UInt64 (%16 : $Builtin.Int64)
1467
+ %18 = struct $UInt64Wrapper (%17 : $UInt64)
1468
+ store %18 to %5 : $*UInt64Wrapper
1469
+ br bb1(%16 : $Builtin.Int64, %18 : $UInt64Wrapper)
1470
+
1471
+ bb3:
1472
+ %21 = tuple ()
1473
+ return %21 : $()
1474
+ }
0 commit comments