diff --git a/lib/SILOptimizer/Utils/ConstantFolding.cpp b/lib/SILOptimizer/Utils/ConstantFolding.cpp index 1a9d88260ebc0..db866baf14395 100644 --- a/lib/SILOptimizer/Utils/ConstantFolding.cpp +++ b/lib/SILOptimizer/Utils/ConstantFolding.cpp @@ -1408,6 +1408,11 @@ static bool isApplyOfBuiltin(SILInstruction &I, BuiltinValueKind kind) { } static bool isApplyOfKnownAvailability(SILInstruction &I) { + // Inlinable functions can be deserialized in other modules which can be + // compiled with a different deployment target. + if (I.getFunction()->getResilienceExpansion() != ResilienceExpansion::Maximal) + return false; + auto apply = FullApplySite::isa(&I); if (!apply) return false; diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index d22e37fabd2c2..bd15c06b2ca89 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -2496,7 +2496,20 @@ usePrespecialized(SILOptFunctionBuilder &funcBuilder, ApplySite apply, auto specializationAvail = SA->getAvailability(); auto &ctxt = funcBuilder.getModule().getSwiftModule()->getASTContext(); auto deploymentAvail = AvailabilityContext::forDeploymentTarget(ctxt); - auto currentFnAvailability = apply.getFunction()->getAvailabilityForLinkage(); + auto currentFn = apply.getFunction(); + auto isInlinableCtxt = (currentFn->getResilienceExpansion() + == ResilienceExpansion::Minimal); + auto currentFnAvailability = currentFn->getAvailabilityForLinkage(); + + // If we are in an inlineable function we can't use the specialization except + // the inlinable function itself has availability we can use. + if (currentFnAvailability.isAlwaysAvailable() && isInlinableCtxt) { + continue; + } + else if (isInlinableCtxt) { + deploymentAvail = currentFnAvailability; + } + if (!currentFnAvailability.isAlwaysAvailable() && !deploymentAvail.isContainedIn(currentFnAvailability)) deploymentAvail = currentFnAvailability; diff --git a/test/SILOptimizer/constant_propagation_availability.swift b/test/SILOptimizer/constant_propagation_availability.swift index 1e8c0e36355c2..154c8aae88c80 100644 --- a/test/SILOptimizer/constant_propagation_availability.swift +++ b/test/SILOptimizer/constant_propagation_availability.swift @@ -1,8 +1,12 @@ // RUN: %target-swift-frontend -target %target-cpu-apple-macos10.15 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_15 %s // RUN: %target-swift-frontend -target %target-cpu-apple-macos10.14 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_14 %s -// RUN: %target-swift-frontend -O -target %target-cpu-apple-macos10.15 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_15 %s +// RUN: %target-swift-frontend -O -target %target-cpu-apple-macos10.15 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_15 --check-prefix=CHECK-macosx10_15_opt %s // RUN: %target-swift-frontend -O -target %target-cpu-apple-macos10.14 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_14 %s +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -O -target %target-cpu-apple-macos10.15 -module-name=Test -emit-module -emit-module-path %t/Test.swiftmodule %s +// RUN: %sil-opt -target %target-cpu-apple-macos10.15 %t/Test.swiftmodule | %FileCheck --check-prefix=CHECK-inlinable %s + // REQUIRES: OS=macosx @available(macOS 10.15, *) @@ -24,6 +28,15 @@ public func testAvailabilityPropagation() -> Int { } } +@inlinable +public func testInlinable() -> Int { + if #available(macOS 10.15, *) { + return newFunction() + } else { + return 0 + } +} + // CHECK-macosx10_15-LABEL: sil @$s33constant_propagation_availability27testAvailabilityPropagationSiyF : $@convention(thin) () -> Int { // CHECK-macosx10_15-NOT: apply // CHECK-macosx10_15: [[F:%.*]] = function_ref @$s33constant_propagation_availability11newFunctionSiyF @@ -31,6 +44,15 @@ public func testAvailabilityPropagation() -> Int { // CHECK-macosx10_15-NOT: apply // CHECK-macosx10_15: } // end sil function '$s33constant_propagation_availability27testAvailabilityPropagationSiyF' +// After serialization, availability checks can be constant folded. + +// CHECK-macosx10_15_opt-LABEL: sil @$s33constant_propagation_availability13testInlinableSiyF : $@convention(thin) () -> Int { +// CHECK-macosx10_15_opt-NOT: apply +// CHECK-macosx10_15_opt: [[F:%.*]] = function_ref @$s33constant_propagation_availability11newFunctionSiyF +// CHECK-macosx10_15_opt: apply [[F]]() : $@convention(thin) () -> Int +// CHECK-macosx10_15_opt-NOT: apply +// CHECK-macosx10_15_opt: } // end sil function '$s33constant_propagation_availability13testInlinableSiyF' + // CHECK-macosx10_14-LABEL: sil @$s33constant_propagation_availability27testAvailabilityPropagationSiyF : $@convention(thin) () -> Int { // CHECK-macosx10_14: [[F:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF // CHECK-macosx10_14: apply [[F]] @@ -41,3 +63,10 @@ public func testAvailabilityPropagation() -> Int { // CHECK-macosx10_14: } // end sil function '$s33constant_propagation_availability27testAvailabilityPropagationSiyF' // CHECK-macosx10_14: sil [readnone] [_semantics "availability.osversion"] @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF + +// CHECK-inlinable-LABEL: sil {{.*}} @$s4Test13testInlinableSiyF : $@convention(thin) () -> Int { +// CHECK-inlinable: [[F:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF +// CHECK-inlinable: apply [[F]] +// CHECK-inlinable: [[F:%.*]] = function_ref @$s4Test11newFunctionSiyF +// CHECK-inlinable: apply [[F]]() : $@convention(thin) () -> Int +// CHECK-inlinable: } // end sil function '$s4Test13testInlinableSiyF'