diff --git a/include/swift/SIL/MemAccessUtils.h b/include/swift/SIL/MemAccessUtils.h index 84fabd54487f9..07a0002e37559 100644 --- a/include/swift/SIL/MemAccessUtils.h +++ b/include/swift/SIL/MemAccessUtils.h @@ -638,6 +638,13 @@ class AccessBase : public AccessRepresentation { return findOwnershipReferenceRoot(getReference()); } + /// Return the OSSA root of the reference being accessed + /// looking through struct_extract, tuple_extract, etc. + /// Precondition: isReference() is true. + SILValue getOwnershipReferenceAggregate() const { + return findOwnershipReferenceAggregate(getReference()); + } + /// Return the storage root of the reference being accessed. /// /// Precondition: isReference() is true. diff --git a/lib/SIL/Utils/OwnershipUtils.cpp b/lib/SIL/Utils/OwnershipUtils.cpp index 1c21e3e8f7e7a..12ca55b1167ee 100644 --- a/lib/SIL/Utils/OwnershipUtils.cpp +++ b/lib/SIL/Utils/OwnershipUtils.cpp @@ -1093,7 +1093,7 @@ bool AddressOwnership::areUsesWithinLifetime( if (!base.hasLocalOwnershipLifetime()) return true; - SILValue root = base.getOwnershipReferenceRoot(); + SILValue root = base.getOwnershipReferenceAggregate(); BorrowedValue borrow(root); if (borrow) return borrow.areUsesWithinExtendedScope(uses, &deadEndBlocks); diff --git a/test/SILOptimizer/cse_ossa_nontrivial.sil b/test/SILOptimizer/cse_ossa_nontrivial.sil index 71b098c4818a8..590c2c7c020f7 100644 --- a/test/SILOptimizer/cse_ossa_nontrivial.sil +++ b/test/SILOptimizer/cse_ossa_nontrivial.sil @@ -1010,3 +1010,26 @@ bb0: return %t : $() } +// CHECK-LABEL: sil [ossa] @test_aggreate_tail_addr : +// CHECK: ref_tail_addr +// CHECK: ref_tail_addr +// CHECK-LABEL: } // end sil function 'test_aggreate_tail_addr' +sil [ossa] @test_aggreate_tail_addr : $@convention(thin) (@owned _NativeDictionary) -> () { +bb0(%0 : @owned $_NativeDictionary): + %1 = move_value [lexical] %0 : $_NativeDictionary + %2 = begin_borrow %1 : $_NativeDictionary + %3 = struct_extract %2 : $_NativeDictionary, #_NativeDictionary._storage + %4 = copy_value %3 : $__RawDictionaryStorage + %5 = ref_tail_addr %3 : $__RawDictionaryStorage, $_UnsafeBitset.Word + %6 = load [trivial] %5 : $*_UnsafeBitset.Word + end_borrow %2 : $_NativeDictionary + %8 = begin_borrow %4 : $__RawDictionaryStorage + %9 = ref_tail_addr %8 : $__RawDictionaryStorage, $_UnsafeBitset.Word + %10 = struct_element_addr %9 : $*_UnsafeBitset.Word, #_UnsafeBitset.Word.value + %11 = struct_element_addr %10 : $*UInt, #UInt._value + %12 = load [trivial] %11 : $*Builtin.Int64 + end_borrow %8 : $__RawDictionaryStorage + destroy_value %4 : $__RawDictionaryStorage + destroy_value %1 : $_NativeDictionary + unreachable +}