blob: ad62eb5dbd6acb12f8ef5112e993a6953badef25 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -diagnostic-constant-propagation | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all %s -performance-constant-propagation | %FileCheck %s
import Builtin
struct UInt {
var value: Builtin.Word
}
struct Int {
var value: Builtin.Word
}
struct Bool {
var value: Builtin.Int1
}
struct Int64 {
var value: Builtin.Int64
}
struct UInt64 {
var value: Builtin.Int64
}
// Compute an expression using a chain of arithmetic with overflow instructions: 2 * (2 + 3) - 3
sil @fold_arithmetic_with_overflow : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, 2
%110 = integer_literal $Builtin.Int64, 3
%18 = builtin "int_sadd_with_overflow_Int64"(%0 : $Builtin.Int64, %110 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
%19 = tuple_extract %18 : $(Builtin.Int64, Builtin.Int1), 0
%20 = builtin "int_smul_with_overflow_Int64"(%0 : $Builtin.Int64, %19 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 0
%22 = builtin "int_ssub_with_overflow_Int64"(%21 : $Builtin.Int64, %110 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1)
%23 = tuple_extract %22 : $(Builtin.Int64, Builtin.Int1), 0
return %23 : $Builtin.Int64
// CHECK-LABEL: sil @fold_arithmetic_with_overflow
// CHECK-NOT: integer_literal $Builtin.Int64, 2
// CHECK-NOT: integer_literal $Builtin.Int64, 3
// CHECK-NOT: integer_literal $Builtin.Int64, 0
// CHECK-NOT: builtin
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 7
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
}
// Fold casts. (This test assumes that DCE does not run, otherwise the unreachable blocks will get removed.)
sil @fold_trunc : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int128, 22
%2 = builtin "trunc_Int128_Int64"(%0 : $Builtin.Int128) : $Builtin.Int64
br bb4(%2 : $Builtin.Int64)
bb1:
%3 = integer_literal $Builtin.Int8, 23
%5 = builtin "sext_Int8_Int64"(%3 : $Builtin.Int8) : $Builtin.Int64
br bb4(%5 : $Builtin.Int64)
bb2:
%6 = integer_literal $Builtin.Int8, 24
%8 = builtin "zext_Int8_Int64"(%6 : $Builtin.Int8) : $Builtin.Int64
br bb4(%8 : $Builtin.Int64)
bb4(%100 : $Builtin.Int64):
return %100 : $Builtin.Int64
// CHECK-LABEL: sil @fold_trunc
// CHECK-NOT: integer_literal $Builtin.Int128, 22
// CHECK: integer_literal $Builtin.Int64, 22
// CHECK-NOT: integer_literal $Builtin.Int8, 23
// CHECK: integer_literal $Builtin.Int64, 23
// CHECK-NOT: integer_literal $Builtin.Int8, 24
// CHECK: integer_literal $Builtin.Int64, 24
}
sil @test_tuple_extract_folding : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, 5
%1 = integer_literal $Builtin.Int1, 0
%2 = tuple (%0 : $Builtin.Int64, %1 : $Builtin.Int1)
%3 = tuple_extract %2 : $(Builtin.Int64, Builtin.Int1), 0
return %3 : $Builtin.Int64
// CHECK-LABEL: sil @test_tuple_extract_folding
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 5
// CHECK-NEXT: return %0 : $Builtin.Int64
// CHECK-NEXT: }
}
sil @test_struct_extract_folding_first : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, 2
%1 = struct $Int64 (%0 : $Builtin.Int64)
%2 = struct_extract %1 : $Int64, #Int64.value
return %2 : $Builtin.Int64
// CHECK-LABEL: sil @test_struct_extract_folding_first
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 2
// CHECK-NEXT: return %0 : $Builtin.Int64
// CHECK-NEXT: }
}
struct TwoValueStruct {
var a : Builtin.Int64
var b : Builtin.Int64
}
sil @test_struct_extract_folding_second : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, 2
%1 = integer_literal $Builtin.Int64, 20
%2 = struct $TwoValueStruct (%0 : $Builtin.Int64, %1 : $Builtin.Int64)
%3 = struct_extract %2 : $TwoValueStruct, #TwoValueStruct.b
return %3 : $Builtin.Int64
// CHECK-LABEL: sil @test_struct_extract_folding_second
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 20
// CHECK-NEXT: return %0 : $Builtin.Int64
// CHECK-NEXT: }
}
sil @test_struct_extract_folding_third : $() -> Bool {
bb0:
%0 = integer_literal $Builtin.Int64, 200
%a = integer_literal $Builtin.Int1, 1
%1 = struct $Bool (%a : $Builtin.Int1)
%2 = tuple (%0 : $Builtin.Int64, %1 : $Bool)
%3 = tuple_extract %2 : $(Builtin.Int64, Bool), 1
return %3 : $Bool
// CHECK-LABEL: sil @test_struct_extract_folding_third
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1
// CHECK-NEXT: %1 = struct $Bool
// CHECK-NEXT: return %1 : $Bool
// CHECK-NEXT: }
}
sil @testChainingCCP : $@convention(thin) () -> Builtin.Int1 {
bb0:
%2 = integer_literal $Builtin.Int64, 0
%3 = struct $Int64 (%2 : $Builtin.Int64)
%4 = struct_extract %3 : $Int64, #Int64.value
%5 = builtin "trunc_Int64_Int1"(%4 : $Builtin.Int64) : $Builtin.Int1
return %5 : $Builtin.Int1
// CHECK-LABEL: sil @testChainingCCP
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: return %0 : $Builtin.Int1
// CHECK-NEXT: }
}
sil @testDivision : $@convention(thin) () -> Builtin.Int8 {
bb0:
%1 = integer_literal $Builtin.Int8, 6
%2 = integer_literal $Builtin.Int8, 3
%3 = builtin "sdiv_Int8"(%1: $Builtin.Int8, %2: $Builtin.Int8) : $Builtin.Int8
return %3 : $Builtin.Int8
// CHECK-LABEL: sil @testDivision
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int8, 2
// CHECK-NEXT: return %0 : $Builtin.Int8
// CHECK-NEXT: }
}
sil @testRem : $@convention(thin) () -> Builtin.Int64 {
bb0:
%1 = integer_literal $Builtin.Int64, 10
%2 = integer_literal $Builtin.Int64, 2
%3 = builtin "urem_Int64"(%1 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
return %3 : $Builtin.Int64
// CHECK-LABEL: sil @testRem
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 0
// CHECK-NEXT: return %0 : $Builtin.Int64
// CHECK-NEXT: }
}
sil @testFoldingIntBinaryPredicates : $@convention(thin) () -> () {
bb0:
%1 = integer_literal $Builtin.Int1, 1
%2 = integer_literal $Builtin.Int1, 0
%4 = builtin "cmp_eq_Int1"(%1 : $Builtin.Int1, %2 : $Builtin.Int1) : $Builtin.Int1
%11 = integer_literal $Builtin.Int32, 21
%12 = integer_literal $Builtin.Int32, 12
%14 = builtin "cmp_ne_Int32"(%11 : $Builtin.Int32, %12 : $Builtin.Int32) : $Builtin.Int1
%16 = builtin "cmp_sgt_Int32"(%12 : $Builtin.Int32, %11 : $Builtin.Int32) : $Builtin.Int1
%18 = builtin "cmp_ult_Int32"(%12 : $Builtin.Int32, %11 : $Builtin.Int32) : $Builtin.Int1
%5 = tuple ()
return %5 : $()
// CHECK-LABEL: sil @testFoldingIntBinaryPredicates
// CHECK: bb
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
// CHECK-NEXT: tuple
// CHECK-NEXT: return
}
// fold_binary_bitwise
sil @fold_binary_bitwise : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, 1 // users: %7, %6, %5
%1 = integer_literal $Builtin.Int64, 0 // users: %7, %6, %5
%5 = builtin "and_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int64
%6 = builtin "or_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int64
%7 = builtin "xor_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int64 // user: %8
return %7 : $Builtin.Int64 // id: %8
// CHECK-LABEL: sil @fold_binary_bitwise
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 0
// CHECK_NEXT: %1 = integer_literal $Builtin.Int64, 1
// CHECK_NEXT: %2 = integer_literal $Builtin.Int64, 1
// CHECK_NEXT: return %2 : $Builtin.Int64
}
// fold_shifts
sil @fold_shifts : $@convention(thin) () -> Builtin.Int64 {
bb0:
%0 = integer_literal $Builtin.Int64, -32 // users: %9, %8
%1 = integer_literal $Builtin.Int64, 32 // users: %11, %10
%2 = integer_literal $Builtin.Int64, 3 // users: %11, %10, %9, %8
%3 = integer_literal $Builtin.Int64, 1 // user: %12
%4 = integer_literal $Builtin.Int64, 5 // user: %12
%8 = builtin "ashr_Int64"(%0 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
%9 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
%10 = builtin "ashr_Int64"(%1 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
%11 = builtin "lshr_Int64"(%1 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
%12 = builtin "shl_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) : $Builtin.Int64 // user: %13
return %12 : $Builtin.Int64 // id: %13
// CHECK-LABEL: sil @fold_shifts
// CHECK: bb0:
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, -4
// CHECK-NEXT: %1 = integer_literal $Builtin.Int64, 2305843009213693948
// CHECK-NEXT: %2 = integer_literal $Builtin.Int64, 4
// CHECK-NEXT: %3 = integer_literal $Builtin.Int64, 4
// CHECK-NEXT: %4 = integer_literal $Builtin.Int64, 32
// CHECK-NEXT: return %4 : $Builtin.Int64
}
// fold_float_operations
sil @fold_float_operations : $@convention(thin) () -> Builtin.FPIEEE64 {
bb0:
%4 = float_literal $Builtin.FPIEEE64, 0x402E4CCCCCCCCCCD // 15.15
%11 = float_literal $Builtin.FPIEEE64, 0x400A666666666666 // 3.2999999999999998 // user: %12
%8 = builtin "fadd_FPIEEE64"(%4 : $Builtin.FPIEEE64, %11 : $Builtin.FPIEEE64) : $Builtin.FPIEEE64
%9 = builtin "fdiv_FPIEEE64"(%4 : $Builtin.FPIEEE64, %11 : $Builtin.FPIEEE64) : $Builtin.FPIEEE64
%10 = builtin "fsub_FPIEEE64"(%4 : $Builtin.FPIEEE64, %11 : $Builtin.FPIEEE64) : $Builtin.FPIEEE64
%13 = builtin "fmul_FPIEEE64"(%4 : $Builtin.FPIEEE64, %11 : $Builtin.FPIEEE64) : $Builtin.FPIEEE64
return %13 : $Builtin.FPIEEE64
// CHECK-LABEL: sil @fold_float_operations
// CHECK: bb0:
// CHECK-NEXT: %0 = float_literal $Builtin.FPIEEE64, 0x4032733333333333
// CHECK-NEXT: %1 = float_literal $Builtin.FPIEEE64, 0x40125D1745D1745D
// CHECK-NEXT: %2 = float_literal $Builtin.FPIEEE64, 0x4027B33333333334
// CHECK-NEXT: %3 = float_literal $Builtin.FPIEEE64, 0x4048FF5C28F5C28F
// CHECK-NEXT: return %3 : $Builtin.FPIEEE64
}
// rdar://15729207 - Verify that constant folding doesn't leave around obviously
// dead cond_fail instructions.
sil @fold_condfail_instructions : $@convention(thin) () -> Int64 {
bb0:
%0 = integer_literal $Builtin.Int2048, 1 // user: %2
%2 = builtin "s_to_s_checked_trunc_Int2048_Int64"(%0 : $Builtin.Int2048) : $(Builtin.Int64, Builtin.Int1) // user: %3
%3 = tuple_extract %2 : $(Builtin.Int64, Builtin.Int1), 0 // user: %4
%4 = struct $Int64 (%3 : $Builtin.Int64) // users: %14, %5
%6 = integer_literal $Builtin.Int2048, 2 // user: %8
%8 = builtin "s_to_s_checked_trunc_Int2048_Int64"(%6 : $Builtin.Int2048) : $(Builtin.Int64, Builtin.Int1) // user: %9
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0 // user: %10
%10 = struct $Int64 (%9 : $Builtin.Int64) // users: %15, %11
%12 = integer_literal $Builtin.Int1, -1 // user: %16
%14 = struct_extract %4 : $Int64, #Int64.value // user: %16
%15 = struct_extract %10 : $Int64, #Int64.value // user: %16
%16 = builtin "sadd_with_overflow_Int64"(%14 : $Builtin.Int64, %15 : $Builtin.Int64, %12 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // users: %18, %17
%17 = tuple_extract %16 : $(Builtin.Int64, Builtin.Int1), 0 // user: %19
%18 = tuple_extract %16 : $(Builtin.Int64, Builtin.Int1), 1 // user: %20
%19 = struct $Int64 (%17 : $Builtin.Int64) // user: %21
cond_fail %18 : $Builtin.Int1 // id: %20
return %19 : $Int64 // id: %21
// CHECK-LABEL: sil @fold_condfail_instructions
// CHECK: bb0
// CHECK-NEXT: integer_literal{{.*}}3
// CHECK-NEXT: struct
// CHECK-NEXT: return
}
// Make sure that we properly handle functions eliminated by CCP by removing
// from the worklist. If we don't the following (reduced) test case will blow
// up.
// CHECK-LABEL: sil @properly_handle_eliminated_instructions_in_worklist : $@convention(method) (Bool, @inout UInt) -> () {
sil @properly_handle_eliminated_instructions_in_worklist : $@convention(method) (Bool, @inout UInt) -> () {
bb0(%0 : $Bool, %1 : $*UInt):
%2 = load %1 : $*UInt
%3 = integer_literal $Builtin.Int2048, 1
%5 = builtin "s_to_u_checked_trunc_Int2048_Word"(%3 : $Builtin.Int2048) : $(Builtin.Word, Builtin.Int1)
%6 = tuple_extract %5 : $(Builtin.Word, Builtin.Int1), 0
%7 = tuple_extract %5 : $(Builtin.Word, Builtin.Int1), 1
%8 = struct $UInt (%6 : $Builtin.Word)
%9 = integer_literal $Builtin.Int2048, 0
%11 = builtin "s_to_u_checked_trunc_Int2048_Word"(%9 : $Builtin.Int2048) : $(Builtin.Word, Builtin.Int1)
%12 = tuple_extract %11 : $(Builtin.Word, Builtin.Int1), 0
%13 = tuple_extract %11 : $(Builtin.Word, Builtin.Int1), 1
%14 = struct $UInt (%12 : $Builtin.Word)
%15 = integer_literal $Builtin.Int2048, 1
%17 = builtin "s_to_u_checked_trunc_Int2048_Word"(%15 : $Builtin.Int2048) : $(Builtin.Word, Builtin.Int1)
%18 = tuple_extract %17 : $(Builtin.Word, Builtin.Int1), 0
%19 = tuple_extract %17 : $(Builtin.Word, Builtin.Int1), 1
%20 = struct $UInt (%18 : $Builtin.Word)
%22 = struct_extract %14 : $UInt, #UInt.value
%23 = struct_extract %20 : $UInt, #UInt.value
%25 = integer_literal $Builtin.Int2048, 0
%27 = builtin "s_to_s_checked_trunc_Int2048_Word"(%25 : $Builtin.Int2048) : $(Builtin.Word, Builtin.Int1)
%28 = tuple_extract %27 : $(Builtin.Word, Builtin.Int1), 0
%29 = tuple_extract %27 : $(Builtin.Word, Builtin.Int1), 1
%30 = struct $Int (%28 : $Builtin.Word)
%31 = struct_extract %30 : $Int, #Int.value
%32 = builtin "trunc_Word_Int1"(%31 : $Builtin.Word) : $Builtin.Int1
%33 = struct $Bool (%32 : $Builtin.Int1)
%34 = struct_extract %33 : $Bool, #Bool.value
%35 = builtin "usub_with_overflow_Word"(%22 : $Builtin.Word, %23 : $Builtin.Word, %34 : $Builtin.Int1) : $(Builtin.Word, Builtin.Int1)
%36 = tuple_extract %35 : $(Builtin.Word, Builtin.Int1), 0
%37 = tuple_extract %35 : $(Builtin.Word, Builtin.Int1), 1
%38 = struct $UInt (%36 : $Builtin.Word)
%39 = struct $Bool (%37 : $Builtin.Int1)
%40 = tuple (%38 : $UInt, %39 : $Bool)
%41 = tuple_extract %40 : $(UInt, Bool), 0
%42 = tuple_extract %40 : $(UInt, Bool), 1
%44 = struct_extract %8 : $UInt, #UInt.value
%45 = struct_extract %41 : $UInt, #UInt.value
%46 = builtin "xor_Word"(%44 : $Builtin.Word, %45 : $Builtin.Word) : $Builtin.Word
%47 = struct $UInt (%46 : $Builtin.Word)
%49 = struct_extract %2 : $UInt, #UInt.value
%50 = struct_extract %47 : $UInt, #UInt.value
%51 = builtin "and_Word"(%49 : $Builtin.Word, %50 : $Builtin.Word) : $Builtin.Word
%52 = struct $UInt (%51 : $Builtin.Word)
%53 = tuple ()
return %53 : $()
}
// CHECK-LABEL: sil @constant_expect_hint
// CHECK: bb0:
// CHECK-NEXT: [[INT1:%[0-9]+]] = integer_literal $Builtin.Int1, 0
// CHECK-NEXT: [[INT2:%[0-9]+]] = integer_literal $Builtin.Int32, 5
// CHECK-NEXT: [[INT3:%[0-9]+]] = integer_literal $Builtin.Int64, 32
// CHECK-NEXT: [[TUPLE:%[0-9]+]] = tuple ([[INT1]] : $Builtin.Int1, [[INT2]] : $Builtin.Int32, [[INT3]] : $Builtin.Int64)
// CHECK-NEXT: return [[TUPLE]]
// CHECK-NEXT: }
sil @constant_expect_hint : $@convention(thin) () -> (Builtin.Int1, Builtin.Int32, Builtin.Int64) {
bb0:
%0 = integer_literal $Builtin.Int1, 0
%1 = integer_literal $Builtin.Int32, 5
%2 = integer_literal $Builtin.Int64, 32
%3 = integer_literal $Builtin.Int1, 1
%4 = integer_literal $Builtin.Int32, 400
%5 = integer_literal $Builtin.Int64, 5000
%9 = builtin "int_expect_Int1"(%0 : $Builtin.Int1, %3 : $Builtin.Int1) : $Builtin.Int1
%10 = builtin "int_expect_Int32"(%1 : $Builtin.Int32, %4 : $Builtin.Int32) : $Builtin.Int32
%11 = builtin "int_expect_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int64
%12 = tuple (%9 : $Builtin.Int1, %10 : $Builtin.Int32, %11 : $Builtin.Int64)
return %12 : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)
}
// CHECK-LABEL: sil @constant_fold_indexing_inst_of_0 : $@convention(thin) (Builtin.RawPointer) -> (Builtin.Int8, Builtin.Int8) {
// CHECK: bb0
// CHECK-NEXT: pointer_to_address
// CHECK-NEXT: pointer_to_address
// CHECK-NEXT: load
// CHECK-NEXT: load
// CHECK-NEXT: tuple
// CHECK-NEXT: return
sil @constant_fold_indexing_inst_of_0 : $@convention(thin) (Builtin.RawPointer) -> (Builtin.Int8, Builtin.Int8) {
bb0(%0 : $Builtin.RawPointer):
%1 = integer_literal $Builtin.Word, 0
%2 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Builtin.Int8
%3 = index_addr %2 : $*Builtin.Int8, %1 : $Builtin.Word
%4 = index_raw_pointer %0 : $Builtin.RawPointer, %1 : $Builtin.Word
%5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.Int8
%6 = load %3 : $*Builtin.Int8
%7 = load %5 : $*Builtin.Int8
%8 = tuple(%6 : $Builtin.Int8, %7 : $Builtin.Int8)
return %8 : $(Builtin.Int8, Builtin.Int8)
}
// CHECK-LABEL: sil @constant_assume_non_negative
// CHECK: bb0:
// CHECK-NEXT: [[I:%[0-9]+]] = integer_literal $Builtin.Word, 27
// CHECK-NEXT: return [[I]]
// CHECK-NEXT: }
sil @constant_assume_non_negative : $@convention(thin) () -> Builtin.Word {
%0 = integer_literal $Builtin.Word, 27
%1 = builtin "assumeNonNegative_Word"(%0 : $Builtin.Word) : $Builtin.Word
return %0 : $Builtin.Word
}
// CHECK-LABEL: sil @constant_fold_fptrunc
// CHECK: bb0:
// CHECK-NEXT: %0 = float_literal
// CHECK-NEXT: %1 = tuple ()
// CHECK-NEXT: return
// CHECK-NEXT: }
sil @constant_fold_fptrunc : $@convention(thin) () -> () {
bb0:
%0 = float_literal $Builtin.FPIEEE80, 0x4000C90E5604189374BC // 3.14149999999999999991 // user: %1
%1 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%0 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %2
%3 = tuple ()
return %3 : $() // id: %3
}
struct Value {}
class AnObject {}
// CHECK-LABEL: sil @replace_unconditional_check_cast_failure
// CHECK: bb2:
// CHECK: alloc_stack $AnObject
// CHECK: store undef to %0
// CHECK: dealloc_stack
// CHECK: builtin "int_trap"()
// CHECK: unreachable
sil @replace_unconditional_check_cast_failure : $@convention(thin) (Builtin.Int1, @guaranteed AnObject) -> (@out Value) {
bb0(%2 : $*Value, %0 : $Builtin.Int1, %1 : $AnObject):
cond_br %0, bb1, bb2
bb1:
%3 = tuple()
return %3 : $()
bb2:
%31 = alloc_stack $AnObject
store %1 to %31 : $*AnObject
strong_retain %1 : $AnObject
unconditional_checked_cast_addr take_always AnObject in %31 : $*AnObject to Value in %2 : $*Value
%32 = alloc_stack $AnObject
dealloc_stack %32: $*AnObject
dealloc_stack %31 : $*AnObject
br bb1
}