diff --git a/SwiftCompilerSources/Sources/SIL/Argument.swift b/SwiftCompilerSources/Sources/SIL/Argument.swift index 9106c881bc437..5921415ca2565 100644 --- a/SwiftCompilerSources/Sources/SIL/Argument.swift +++ b/SwiftCompilerSources/Sources/SIL/Argument.swift @@ -285,7 +285,7 @@ public struct ArgumentConventions : Collection, CustomStringConvertible { if let paramIdx = parameterIndex(for: argumentIndex) { return convention.parameters[paramIdx].convention } - let resultInfo = convention.indirectSILResults[argumentIndex] + let resultInfo = convention.indirectSILResult(at: argumentIndex) return ArgumentConvention(result: resultInfo.convention) } @@ -293,7 +293,7 @@ public struct ArgumentConventions : Collection, CustomStringConvertible { if parameterIndex(for: argumentIndex) != nil { return nil } - return convention.indirectSILResults[argumentIndex] + return convention.indirectSILResult(at: argumentIndex) } public subscript(parameter argumentIndex: Int) -> ParameterInfo? { diff --git a/SwiftCompilerSources/Sources/SIL/FunctionConvention.swift b/SwiftCompilerSources/Sources/SIL/FunctionConvention.swift index 4af73a1d92d0f..3d8ea91b0f531 100644 --- a/SwiftCompilerSources/Sources/SIL/FunctionConvention.swift +++ b/SwiftCompilerSources/Sources/SIL/FunctionConvention.swift @@ -57,11 +57,15 @@ public struct FunctionConvention : CustomStringConvertible { : SILFunctionType_getNumPackResults(functionType.bridged) } - /// Indirect results including the error. - public var indirectSILResults: LazyFilterSequence { - hasLoweredAddresses - ? results.lazy.filter { $0.isSILIndirect } - : results.lazy.filter { $0.convention == .pack } + /// Returns the indirect result - including the error - at `index`. + public func indirectSILResult(at index: Int) -> ResultInfo { + let indirectResults = results.lazy.filter { + hasLoweredAddresses ? $0.isSILIndirect : $0.convention == .pack + } + // Note that subscripting a LazyFilterCollection (with the base index, e.g. `Int`) does not work + // as expected, because it returns the nth element of the base collection! + // Therefore we need to implement the subscript "manually". + return indirectResults.enumerated().first{ $0.offset == index }!.element } public var parameters: Parameters { diff --git a/test/SILOptimizer/mem-behavior.sil b/test/SILOptimizer/mem-behavior.sil index d7c8bbf35462f..10ca5b49bd82b 100644 --- a/test/SILOptimizer/mem-behavior.sil +++ b/test/SILOptimizer/mem-behavior.sil @@ -1941,3 +1941,19 @@ bb0(%0 : $*C, %1 : $*C, %2 : @guaranteed $C): %99 = tuple () return %99 : $() } + +sil @returns_tuple : $@convention(thin) () -> (Int64, @out UInt64) + +// CHECK-LABEL: @aliasing_apply_with_direct_and_indirect_result +// CHECK: PAIR #0. +// CHECK-NEXT: %2 = apply %1(%0) : $@convention(thin) () -> (Int64, @out UInt64) +// CHECK-NEXT: %0 = argument of bb0 : $*UInt64 +// CHECK-NEXT: r=0,w=1 +sil [ossa] @aliasing_apply_with_direct_and_indirect_result : $@convention(thin) () -> @out UInt64 { +bb0(%0 : $*UInt64): + %1 = function_ref @returns_tuple : $@convention(thin) () -> (Int64, @out UInt64) + %2 = apply %1(%0) : $@convention(thin) () -> (Int64, @out UInt64) + %99 = tuple () + return %99 : $() +} + diff --git a/test/SILOptimizer/redundant_load_elim_ossa.sil b/test/SILOptimizer/redundant_load_elim_ossa.sil index 8ddedacace959..cf19d51fd2361 100644 --- a/test/SILOptimizer/redundant_load_elim_ossa.sil +++ b/test/SILOptimizer/redundant_load_elim_ossa.sil @@ -1708,6 +1708,24 @@ bb0(%0 : $*ExistentialIntPair, %1 : $*ExistentialIntPair): return %4 } +sil @returns_tuple : $@convention(thin) () -> (Int64, @out UInt64) + +// CHECK-LABEL: sil [ossa] @aliasing_apply_with_direct_and_indirect_result : +// CHECK: apply +// CHECK: [[L:%.*]] = load +// CHECK: return [[L]] +// CHECK-LABEL: } // end sil function 'aliasing_apply_with_direct_and_indirect_result' +sil [ossa] @aliasing_apply_with_direct_and_indirect_result : $@convention(thin) (UInt64) -> UInt64 { +bb0(%0 : $UInt64): + %4 = alloc_stack $UInt64 + store %0 to [trivial] %4 + %11 = function_ref @returns_tuple : $@convention(thin) () -> (Int64, @out UInt64) + %12 = apply %11(%4) : $@convention(thin) () -> (Int64, @out UInt64) + %13 = load [trivial] %4 + dealloc_stack %4 + return %13 +} + // CHECK-LABEL: sil [ossa] @struct_of_optional_none : // CHECK: [[E:%.*]] = enum // CHECK: [[S:%.*]] = struct $S ([[E]] : $Optional)