Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/SIL/MemAccessUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ inline Operand *getAccessProjectionOperand(SingleValueInstruction *svi) {
case SILInstructionKind::TupleElementAddrInst:
case SILInstructionKind::IndexAddrInst:
case SILInstructionKind::TailAddrInst:
case SILInstructionKind::InitEnumDataAddrInst:
// open_existential_addr and unchecked_take_enum_data_addr are problematic
// because they both modify memory and are access projections. Ideally, they
// would not be casts, but will likely be eliminated with opaque values.
Expand Down
5 changes: 5 additions & 0 deletions lib/SIL/Utils/MemAccessUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ class AccessPathVisitor : public FindAccessVisitorImpl<AccessPathVisitor> {
// Ignore everything in getAccessProjectionOperand that is an access
// projection with no affect on the access path.
assert(isa<OpenExistentialAddrInst>(projectedAddr)
|| isa<InitEnumDataAddrInst>(projectedAddr)
|| isa<UncheckedTakeEnumDataAddrInst>(projectedAddr)
|| isa<ProjectBoxInst>(projectedAddr));
}
Expand Down Expand Up @@ -1390,6 +1391,10 @@ AccessPathDefUseTraversal::visitSingleValueUser(SingleValueInstruction *svi,
return IgnoredUse;
}

case SILInstructionKind::InitEnumDataAddrInst:
pushUsers(svi, dfs);
return IgnoredUse;

// open_existential_addr and unchecked_take_enum_data_addr are classified as
// access projections, but they also modify memory. Both see through them and
// also report them as uses.
Expand Down
5 changes: 3 additions & 2 deletions test/SILOptimizer/access_marker_verify.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,9 @@ func testInitGenericEnum<T>(t: T) -> GenericEnum<T>? {
// CHECK: copy_addr %1 to [initialization] [[ADR1]] : $*T
// CHECK: [[STK:%.*]] = alloc_stack $GenericEnum<T>
// CHECK: [[ENUMDATAADDR:%.*]] = init_enum_data_addr [[STK]]
// CHECK-NOT: begin_access
// CHECK: copy_addr [take] [[ADR1]] to [initialization] [[ENUMDATAADDR]] : $*T
// CHECK: [[ACCESSENUM:%.*]] = begin_access [modify] [unsafe] [[ENUMDATAADDR]] : $*T
// CHECK: copy_addr [take] [[ADR1]] to [initialization] [[ACCESSENUM]] : $*T
// CHECK: end_access [[ACCESSENUM]] : $*T
// CHECK: inject_enum_addr
// CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[PROJ]]
// CHECK: copy_addr [take] %{{.*}} to [[ACCESS]] : $*GenericEnum<T>
Expand Down
51 changes: 51 additions & 0 deletions test/SILOptimizer/accesspath_uses.sil
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,54 @@ bb5:
%999 = tuple ()
return %999 : $()
}

// CHECK-LABEL: @test_init_enum_addr
// CHECK: ###For MemOp: store %0 to [init] %2 : $*AnyObject
// CHECK: Stack %1 = alloc_stack $Optional<AnyObject>
// CHECK: Path: ()
// CHECK: Exact Uses {
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject
// CHECK-NEXT: Path: ()
// CHECK-NEXT: inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
// CHECK-NEXT: Path: ()
// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: dealloc_stack %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: }
// CHECK: ###For MemOp: inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
// CHECK: Stack %1 = alloc_stack $Optional<AnyObject>
// CHECK: Path: ()
// CHECK: Exact Uses {
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject
// CHECK-NEXT: Path: ()
// CHECK-NEXT: inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
// CHECK-NEXT: Path: ()
// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: dealloc_stack %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: }
// CHECK: ###For MemOp: %5 = load [copy] %1 : $*Optional<AnyObject>
// CHECK: Stack %1 = alloc_stack $Optional<AnyObject>
// CHECK: Path: ()
// CHECK: Exact Uses {
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*AnyObject
// CHECK-NEXT: Path: ()
// CHECK-NEXT: inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
// CHECK-NEXT: Path: ()
// CHECK-NEXT: %{{.*}} = load [copy] %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: dealloc_stack %1 : $*Optional<AnyObject>
// CHECK-NEXT: Path: ()
// CHECK-NEXT: }
sil [ossa] @test_init_enum_addr : $@convention(thin) (@owned AnyObject) -> @owned Optional<AnyObject> {
bb0(%0 : @owned $AnyObject):
%1 = alloc_stack $Optional<AnyObject>
%2 = init_enum_data_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
store %0 to [init] %2 : $*AnyObject
inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
%5 = load [copy] %1 : $*Optional<AnyObject>
dealloc_stack %1 : $*Optional<AnyObject>
return %5 : $Optional<AnyObject>
}
19 changes: 19 additions & 0 deletions test/SILOptimizer/load_borrow_verify.sil
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,22 @@ bb0(%0 : $Int64):
end_access %33 : $*Int64
return %35 : $Int64
}

// CHECK-LABEL: sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () {
// CHECK: bb0(%0 : @owned $AnyObject):
// CHECK: [[ALLOC:%.*]] = alloc_stack $Optional<AnyObject>
// CHECK: init_enum_data_addr [[ALLOC]] : $*Optional<AnyObject>, #Optional.some!enumelt
// CHECK: load_borrow [[ALLOC]] : $*Optional<AnyObject>
// CHECK-LABEL: } // end sil function 'test_borrow_init_enum_addr'
sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () {
bb0(%0 : @owned $AnyObject):
%1 = alloc_stack $Optional<AnyObject>
%2 = init_enum_data_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
store %0 to [init] %2 : $*AnyObject
inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
%5 = load_borrow %1 : $*Optional<AnyObject>
end_borrow %5 : $Optional<AnyObject>
dealloc_stack %1 : $*Optional<AnyObject>
%99 = tuple ()
return %99 : $()
}