// RUN: %target-swift-frontend -primary-file %s -emit-ir| %FileCheck --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s // REQUIRES: CPU=i386 || CPU=x86_64 sil_stage canonical import Swift class A {} class B: A {} class C {} sil_vtable A {} sil_vtable B {} sil_vtable C {} protocol CP: class {} // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @bitcast_trivial(ptr %0) {{.*}} { // CHECK-i386: [[BUF:%.*]] = alloca ptr, align 4 // CHECK-i386: store ptr %0, ptr [[BUF]] // CHECK-i386: [[VALUE_BUF:%.*]] = getelementptr inbounds %TSi, ptr [[BUF]], i32 0, i32 0 // CHECK-i386: [[VALUE:%.*]] = load i32, ptr [[VALUE_BUF]], align 4 // CHECK-i386: ret i32 [[VALUE]] // CHECK-i386: } // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @bitcast_trivial(ptr %0) {{.*}} { // CHECK-x86_64: [[BUF:%.*]] = alloca ptr, align 8 // CHECK-x86_64: store ptr %0, ptr [[BUF]] // CHECK-x86_64: [[VALUE_BUF:%.*]] = getelementptr inbounds %TSi, ptr [[BUF]], i32 0, i32 0 // CHECK-x86_64: [[VALUE:%.*]] = load i64, ptr [[VALUE_BUF]], align 8 // CHECK-x86_64: ret i64 [[VALUE]] // CHECK-x86_64: } sil @bitcast_trivial: $@convention(thin) (C) -> Int { entry(%c : $C): %i = unchecked_trivial_bit_cast %c : $C to $Int return %i : $Int } // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i8 } @bitcast_trivial_optional(i64 %0, i8 %1) {{.*}} { // CHECK-x86_64-NEXT: entry: // CHECK-x86_64-NEXT: %2 = trunc i8 %1 to i1 // CHECK-x86_64-NEXT: %3 = zext i1 %2 to i8 // CHECK-x86_64-NEXT: %4 = insertvalue { i64, i8 } undef, i64 %0, 0 // CHECK-x86_64-NEXT: %5 = insertvalue { i64, i8 } %4, i8 %3, 1 // CHECK-x86_64-NEXT: ret { i64, i8 } %5 sil @bitcast_trivial_optional: $@convention(thin) (Optional) -> Optional { entry(%c : $Optional): %i = unchecked_trivial_bit_cast %c : $Optional to $Optional return %i : $Optional } // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @bitcast_ref(ptr %0) {{.*}} { // CHECK-i386-NEXT: entry: // CHECK-i386-NEXT: [[VALUE:%.*]] = ptrtoint ptr %0 to i32 // CHECK-i386-NEXT: ret i32 [[VALUE]] // CHECK-i386-NEXT: } // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @bitcast_ref(ptr %0) {{.*}} { // CHECK-x86_64-NEXT: entry: // CHECK-x86_64-NEXT: [[VALUE:%.*]] = ptrtoint ptr %0 to i64 // CHECK-x86_64-NEXT: ret i64 [[VALUE]] // CHECK-x86_64-NEXT: } sil @bitcast_ref: $@convention(thin) (C) -> Optional { entry(%c : $C): %o = unchecked_ref_cast %c : $C to $Optional return %o : $Optional } // CHECK-i386-LABEL: define hidden swiftcc i32 @bitcast_ref_optional(i32 %0) {{.*}} { // CHECK-i386-NEXT: entry: // CHECK-i386-NEXT: ret i32 %0 // CHECK-i386-NEXT: } // CHECK-x86_64-LABEL: define hidden swiftcc i64 @bitcast_ref_optional(i64 %0) {{.*}} { // CHECK-x86_64-NEXT: entry: // CHECK-x86_64-NEXT: ret i64 %0 // CHECK-x86_64-NEXT: } sil hidden @bitcast_ref_optional : $@convention(thin) (@owned Optional) -> @owned Optional { bb0(%0 : $Optional): %o = unchecked_ref_cast %0 : $Optional to $Optional return %o : $Optional } // CHECK-x86_64-LABEL: define hidden swiftcc i64 @unchecked_bitwise_cast(i64 %0, i64 %1) {{.*}} { // CHECK-x86_64-NEXT: entry: // CHECK-x86_64-NEXT: alloca <{ %TSi, %TSi }>, align 8 // A bunch of GEPs happen here to get from Int to int. // CHECK-x86_64: store i64 %{{.*}}, ptr %bitcast.elt._value, align 8 // CHECK-x86_64: store i64 %{{.*}}, ptr %bitcast.elt1._value, align 8 // CHECK-x86_64-NEXT: [[VAL:%.*]] = getelementptr inbounds %TSi, ptr %bitcast, i32 0, i32 0 // CHECK-x86_64-NEXT: [[RESULT:%.*]] = load i64, ptr [[VAL]], align 8 // CHECK-x86_64: ret i64 [[RESULT]] // CHECK-x86_64-NEXT: } sil hidden @unchecked_bitwise_cast : $@convention(thin) (Int, Int) -> Int { bb0(%0 : $Int, %1 : $Int): %2 = tuple (%0 : $Int, %1 : $Int) %3 = unchecked_bitwise_cast %2 : $(Int, Int) to $Int return %3 : $Int } // CHECK-x86_64-LABEL: define hidden swiftcc i64 @trivial_bitwise_cast(i64 %0, i64 %1) {{.*}} { // CHECK-x86_64-NOT: trap // CHECK-x86_64-NOT: unreachable // CHECK-x86_64: ret sil hidden [noinline] @trivial_bitwise_cast : $@convention(thin) (Int, Int) -> Int { bb0(%0 : $Int, %1 : $Int): %t1 = tuple (%0 : $Int, %1 : $Int) %i3 = unchecked_trivial_bit_cast %t1 : $(Int, Int) to $Int return %i3 : $Int } // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @unchecked_ref_cast_addr // CHECK-i386: call zeroext i1 @swift_dynamicCast(ptr %0, ptr %{{.*}}, ptr %T, ptr %U, i32 7) // CHECK-x86_64: call zeroext i1 @swift_dynamicCast(ptr %0, ptr %{{.*}}, ptr %T, ptr %U, i64 7) sil @unchecked_ref_cast_addr : $@convention(thin) (@in T) -> @out U { bb0(%0 : $*U, %1 : $*T): %a = alloc_stack $T copy_addr %1 to [init] %a : $*T unchecked_ref_cast_addr T in %a : $*T to U in %0 : $*U dealloc_stack %a : $*T destroy_addr %1 : $*T %r = tuple () return %r : $() } // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @unchecked_ref_cast_class_optional // CHECK-i386: ptrtoint ptr %0 to i32 // CHECK-i386-NEXT: ret i32 // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @unchecked_ref_cast_class_optional // CHECK-x86_64: ptrtoint ptr %0 to i64 // CHECK-x86_64-NEXT: ret i64 sil @unchecked_ref_cast_class_optional : $@convention(thin) (@owned A) -> @owned Optional { bb0(%0 : $A): %2 = unchecked_ref_cast %0 : $A to $Optional return %2 : $Optional } // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @unchecked_ref_cast_optional_optional // CHECK-i386: ret i32 %0 // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @unchecked_ref_cast_optional_optional // CHECK-x86_64: ret i64 %0 sil @unchecked_ref_cast_optional_optional : $@convention(thin) (@owned Optional) -> @owned Optional { bb0(%0 : $Optional): %2 = unchecked_ref_cast %0 : $Optional to $Optional return %2 : $Optional } // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @unchecked_ref_cast_proto_optional // CHECK-i386: ptrtoint ptr %0 to i32 // CHECK-i386-NEXT: ret i32 // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @unchecked_ref_cast_proto_optional // CHECK-x86_64: ptrtoint ptr %0 to i64 // CHECK-x86_64-NEXT: ret i64 sil @unchecked_ref_cast_proto_optional : $@convention(thin) (@owned CP) -> @owned Optional { bb0(%0 : $CP): %2 = unchecked_ref_cast %0 : $CP to $Optional return %2 : $Optional } // CHECK-i386-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @unchecked_ref_cast_optionalproto_optional // CHECK-i386: ret i32 %0 // CHECK-x86_64-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i64 @unchecked_ref_cast_optionalproto_optional // CHECK-x86_64: ret i64 %0 sil @unchecked_ref_cast_optionalproto_optional : $@convention(thin) (@owned Optional) -> @owned Optional { bb0(%0 : $Optional): %2 = unchecked_ref_cast %0 : $Optional to $Optional return %2 : $Optional }