Merge pull request #16828 from gottesmm/pr-84e7c044a8d49ddcb70f6fc1535e1309e96c6a27
[func-sig-opts] Add a regression benchmark that shows overhead from +…
diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
index e5764b7..ee9286b 100644
--- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
+++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
@@ -2,24 +2,6 @@
include(CMakeParseArguments)
include(SwiftBenchmarkUtils)
-# Run a shell command and assign output to a variable or fail with an error.
-# Example usage:
-# runcmd(COMMAND "xcode-select" "-p"
-# VARIABLE xcodepath
-# ERROR "Unable to find current Xcode path")
-function(runcmd)
- cmake_parse_arguments(RUNCMD "" "VARIABLE;ERROR" "COMMAND" ${ARGN})
- execute_process(
- COMMAND ${RUNCMD_COMMAND}
- OUTPUT_VARIABLE ${RUNCMD_VARIABLE}
- RESULT_VARIABLE result
- ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(NOT "${result}" MATCHES "0")
- message(FATAL_ERROR "${RUNCMD_ERROR}")
- endif()
- set(${RUNCMD_VARIABLE} ${${RUNCMD_VARIABLE}} PARENT_SCOPE)
-endfunction(runcmd)
-
function (add_swift_benchmark_library objfile_out sibfile_out)
cmake_parse_arguments(BENCHLIB "" "MODULE_PATH;SOURCE_DIR;OBJECT_DIR" "SOURCES;LIBRARY_FLAGS;DEPENDS" ${ARGN})
diff --git a/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake b/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
index 9c5e6a0..d457bac 100644
--- a/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
+++ b/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
@@ -43,3 +43,22 @@
set("${var_name}" "" PARENT_SCOPE)
endif()
endfunction()
+
+
+# Run a shell command and assign output to a variable or fail with an error.
+# Example usage:
+# runcmd(COMMAND "xcode-select" "-p"
+# VARIABLE xcodepath
+# ERROR "Unable to find current Xcode path")
+function(runcmd)
+ cmake_parse_arguments(RUNCMD "" "VARIABLE;ERROR" "COMMAND" ${ARGN})
+ execute_process(
+ COMMAND ${RUNCMD_COMMAND}
+ OUTPUT_VARIABLE ${RUNCMD_VARIABLE}
+ RESULT_VARIABLE result
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT "${result}" MATCHES "0")
+ message(FATAL_ERROR "${RUNCMD_ERROR}")
+ endif()
+ set(${RUNCMD_VARIABLE} ${${RUNCMD_VARIABLE}} PARENT_SCOPE)
+endfunction(runcmd)
diff --git a/lib/SIL/DynamicCasts.cpp b/lib/SIL/DynamicCasts.cpp
index 56c6c6c..1604f8d 100644
--- a/lib/SIL/DynamicCasts.cpp
+++ b/lib/SIL/DynamicCasts.cpp
@@ -323,10 +323,15 @@
// Casting to a less-optional type can always fail.
} else if (sourceObject) {
- return atBest(classifyDynamicCast(M, sourceObject, target,
- /* isSourceTypeExact */ false,
- isWholeModuleOpts),
- DynamicCastFeasibility::MaySucceed);
+ auto result = atBest(classifyDynamicCast(M, sourceObject, target,
+ /* isSourceTypeExact */ false,
+ isWholeModuleOpts),
+ DynamicCastFeasibility::MaySucceed);
+ if (target.isExistentialType()) {
+ result = atWorst(result, classifyDynamicCastToProtocol(
+ M, source, target, isWholeModuleOpts));
+ }
+ return result;
}
assert(!sourceObject && !targetObject);
diff --git a/test/SILOptimizer/cast_folding.swift b/test/SILOptimizer/cast_folding.swift
index 26a71b9..6f27f50 100644
--- a/test/SILOptimizer/cast_folding.swift
+++ b/test/SILOptimizer/cast_folding.swift
@@ -1032,6 +1032,39 @@
return P.Type.self as? P.Type.Type
}
+protocol PForOptional {
+}
+
+extension Optional: PForOptional {
+}
+
+func testCastToPForOptional<T>(_ t: T) -> Bool {
+ if let _ = t as? PForOptional {
+ return true
+ }
+ return false
+}
+
+// CHECK-LABEL: // testCastToPForOptionalSuccess()
+// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int1, -1
+// CHECK: [[RET:%.*]] = struct $Bool ([[RES]] : $Builtin.Int1)
+// CHECK: return [[RET]] : $Bool
+@inline(never)
+public func testCastToPForOptionalSuccess() -> Bool {
+ let t: Int? = 42
+ return testCastToPForOptional(t)
+}
+
+// CHECK-LABEL: // testCastToPForOptionalFailure()
+// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int1, 0
+// CHECK: [[RET:%.*]] = struct $Bool ([[RES]] : $Builtin.Int1)
+// CHECK: return [[RET]] : $Bool
+@inline(never)
+public func testCastToPForOptionalFailure() -> Bool {
+ let t: Int = 42
+ return testCastToPForOptional(t)
+}
+
print("test0=\(test0())")
print("test1=\(test1())")