// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize // REQUIRES: CPU=i386 || CPU=x86_64 // We have to claim this is raw SIL because there are critical edges from non // cond_br instructions. sil_stage raw import Builtin import Swift protocol P { func f() -> Self } struct S { var v: Int } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testUnconditional0( sil @testUnconditional0 : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): // CHECK: [[T0:%.*]] = alloca [[S:%.*]], align // CHECK: [[T1:%.*]] = bitcast [[S]]* [[T0]] to [[OPAQUE:%swift.opaque]]* // CHECK: [[T2:%.*]] = bitcast [[P:%.*]]* {{%.*}} to [[OPAQUE]]* // CHECK: [[T4:%.*]] = call {{.*}}@"$s12dynamic_cast1P_pMD" // CHECK: call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], %swift.type* [[T4]], %swift.type* {{.*}}, [[INT]] 7) %1 = alloc_stack $S unconditional_checked_cast_addr P in %0 : $*P to S in %1 : $*S destroy_addr %1 : $*S dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testUnconditional1( sil @testUnconditional1 : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): // CHECK: [[T0:%.*]] = alloca [[S:%.*]], align // CHECK: [[T1:%.*]] = bitcast [[S]]* [[T0]] to [[OPAQUE:%swift.opaque]]* // CHECK: [[T2:%.*]] = bitcast [[P:%.*]]* {{%.*}} to [[OPAQUE]]* // CHECK: [[T4:%.*]] = call {{.*}}@"$s12dynamic_cast1P_pMD" // CHECK: call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], %swift.type* [[T4]], %swift.type* {{.*}}, [[INT]] 7) %1 = alloc_stack $S unconditional_checked_cast_addr P in %0 : $*P to S in %1 : $*S destroy_addr %1 : $*S dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testConditional0( sil @testConditional0 : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): // CHECK: [[T0:%.*]] = alloca [[S:%.*]], align // CHECK: [[T1:%.*]] = bitcast [[S]]* [[T0]] to [[OPAQUE:%swift.opaque]]* // CHECK: [[T2:%.*]] = bitcast [[P:%.*]]* {{%.*}} to [[OPAQUE]]* // CHECK: [[T4:%.*]] = call {{.*}}@"$s12dynamic_cast1P_pMD" // CHECK: [[T5:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], %swift.type* [[T4]], %swift.type* {{.*}}, [[INT]] 6) // CHECK: br i1 [[T5]], %1 = alloc_stack $S checked_cast_addr_br take_always P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: destroy_addr %1 : $*S dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testConditional1( sil @testConditional1 : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): // CHECK: [[T0:%.*]] = alloca [[S:%.*]], align // CHECK: [[T1:%.*]] = bitcast [[S]]* [[T0]] to [[OPAQUE:%swift.opaque]]* // CHECK: [[T2:%.*]] = bitcast [[P:%.*]]* {{%.*}} to [[OPAQUE]]* // CHECK: [[T4:%.*]] = call {{.*}}@"$s12dynamic_cast1P_pMD" // CHECK: [[T5:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], %swift.type* [[T4]], %swift.type* {{.*}}, [[INT]] 2) // CHECK: br i1 [[T5]], %1 = alloc_stack $S checked_cast_addr_br take_on_success P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: destroy_addr %1 : $*S dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @testConditional2( sil @testConditional2 : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): // CHECK: [[T0:%.*]] = alloca [[S:%.*]], align // CHECK: [[T1:%.*]] = bitcast [[S]]* [[T0]] to [[OPAQUE:%swift.opaque]]* // CHECK: [[T2:%.*]] = bitcast [[P:%.*]]* {{%.*}} to [[OPAQUE]]* // CHECK: [[T4:%.*]] = call {{.*}}@"$s12dynamic_cast1P_pMD" // CHECK: [[T5:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], %swift.type* [[T4]], %swift.type* {{.*}}, [[INT]] 0) // CHECK: br i1 [[T5]], %1 = alloc_stack $S checked_cast_addr_br copy_on_success P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: destroy_addr %1 : $*S dealloc_stack %1 : $*S %2 = tuple () return %2 : $() }