blob: 4a9700253232e8262d7ce2a86d841f48a06af558 [file] [log] [blame]
// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
// REQUIRES: objc_interop
// We want to check that casts between two types which are both Swift types or
// both are ObjC types are not optimized by the cast optimizer into casts
// to/from ObjC.
sil_stage raw
import Builtin
import Swift
import SwiftShims
import Foundation
// CHECK-LABEL: sil @testSwiftToSwift : $@convention(thin) (@in Set<Int>, @guaranteed Set<Int>)
// CHECK: bb0
// CHECK-NOT: checked_cast_addr_br
// CHECK-NOT: _bridgeToObjectiveC
// CHECK-NOT: _conditionallyBridgeFromObjectiveC_bridgeable
// CHECK: return
sil @testSwiftToSwift : $@convention(thin) (@in Set<Int>, @guaranteed Set<Int>) -> @owned Set<Int> {
bb0(%0 : $*Set<Int>, %1 : $Set<Int>):
%3 = alloc_stack $Set<Int>
copy_addr %0 to [initialization] %3 : $*Set<Int>
%5 = alloc_stack $Set<Int>
checked_cast_addr_br take_always Set<Int> in %3 : $*Set<Int> to Set<Int> in %5 : $*Set<Int>, bb1, bb3
bb1:
destroy_addr %0 : $*Set<Int>
%8 = load %5 : $*Set<Int>
br bb2(%8 : $Set<Int>)
bb2(%14 : $Set<Int>):
dealloc_stack %5 : $*Set<Int>
dealloc_stack %3 : $*Set<Int>
return %14 : $Set<Int>
bb3:
br bb2(%1 : $Set<Int>)
}
// CHECK-LABEL: sil @testObjCToObjC : $@convention(thin) (NSSet, NSSet)
// CHECK: bb0
// CHECK-NOT: checked_cast_br
// CHECK-NOT: BridgeFromObjectiveC
// CHECK-NOT: bridgeToObjectiveC
// CHECK: return
sil @testObjCToObjC : $@convention(thin) (NSSet, NSSet) -> @owned NSSet {
bb0(%0 : $NSSet, %1 : $NSSet):
checked_cast_br %0 : $NSSet to $NSSet, bb1, bb3
bb1(%2 : $NSSet):
br bb2(%2 : $NSSet)
bb2(%14 : $NSSet):
return %14 : $NSSet
bb3:
br bb2(%1 : $NSSet)
}
sil @fail : $@convention(thin) () -> Never
// CHECK-LABEL: sil @testCFToObjC
// CHECK: bb0(
// CHECK-NEXT: [[T0:%.*]] = load %1 : $*CFString
// CHECK-NEXT: [[T1:%.*]] = unchecked_ref_cast [[T0]] : $CFString to $NSString
// CHECK-NEXT: store [[T1]] to %0 : $*NSString
sil @testCFToObjC : $@convention(thin) (@in CFString) -> @out NSString {
bb0(%0 : $*NSString, %1 : $*CFString):
checked_cast_addr_br take_always CFString in %1 : $*CFString to NSString in %0 : $*NSString, bb1, bb2
bb1:
%ret = tuple ()
return %ret : $()
bb2:
%fn = function_ref @fail : $@convention(thin) () -> Never
apply %fn() : $@convention(thin) () -> Never
unreachable
}
// CHECK-LABEL: sil @testCFToSwift
// CHECK: bb0(
// CHECK-NEXT: [[T0:%.*]] = load %1 : $*CFString
// CHECK-NEXT: [[T1:%.*]] = unchecked_ref_cast [[T0]] : $CFString to $NSString
// CHECK: [[FN:%.*]] = function_ref @$sSS10FoundationE34_conditionallyBridgeFromObjectiveC_6resultSbSo8NSStringC_SSSgztFZ : $@convention(method) (@guaranteed NSString, @inout Optional<String>, @thin String.Type) -> Bool
// CHECK: apply [[FN]]([[T1]], {{.*}}, {{.*}})
sil @testCFToSwift : $@convention(thin) (@in CFString) -> @out String {
bb0(%0 : $*String, %1 : $*CFString):
checked_cast_addr_br take_always CFString in %1 : $*CFString to String in %0 : $*String, bb1, bb2
bb1:
%ret = tuple ()
return %ret : $()
bb2:
%fn = function_ref @fail : $@convention(thin) () -> Never
apply %fn() : $@convention(thin) () -> Never
unreachable
}