blob: da56ee17389f61c05fbe62faa022d453fc1602f6 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -remove-redundant-overflow-checks | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
import SwiftShims
sil [noinline] @sink_unsigned_int : $@convention(thin) () -> ()
sil [noinline] @sink_signed_int : $@convention(thin) () -> ()
// CHECK-LABEL: @sub_signed_branch_cond
sil hidden @sub_signed_branch_cond : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 2 // users: %3, %12
%2 = struct_extract %0 : $Int64, #Int64._value // users: %3, %7, %12, %17
%3 = builtin "cmp_slt_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb2, bb1 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 1 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // users: %7, %12, %17
%7 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
// CHECK-NOT: cond_fail
cond_fail %8 : $Builtin.Int1 // id: %9
%10 = function_ref @sink_unsigned_int : $@convention(thin) () -> () // users: %11, %15, %20
%11 = apply %10() : $@convention(thin) () -> ()
%12 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
// CHECK-NOT: cond_fail
cond_fail %13 : $Builtin.Int1 // id: %14
%15 = apply %10() : $@convention(thin) () -> ()
// CHECK that we do not remove the '3' because it is not guarder by the branch.
// CHECK: integer_literal $Builtin.Int64, 3
// CHECK: cond_fail
%16 = integer_literal $Builtin.Int64, 3 // user: %17
%17 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %16 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %18
%18 = tuple_extract %17 : $(Builtin.Int64, Builtin.Int1), 1 // user: %19
cond_fail %18 : $Builtin.Int1 // id: %19
%20 = apply %10() : $@convention(thin) () -> ()
br bb2 // id: %21
bb2: // Preds: bb0 bb1
%22 = tuple () // user: %23
// CHECK: return
return %22 : $() // id: %23
}
// CHECK-LABEL: @sub_signed_branch_cond2
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @sub_signed_branch_cond2: $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 2 // users: %3, %12
%2 = struct_extract %0 : $Int64, #Int64._value // users: %3, %7, %12, %17
%3 = builtin "cmp_sge_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb1, bb2 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 1 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // users: %7, %12, %17
%7 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
cond_fail %8 : $Builtin.Int1 // id: %9
%10 = function_ref @sink_unsigned_int : $@convention(thin) () -> () // users: %11, %15, %20
%11 = apply %10() : $@convention(thin) () -> ()
%12 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
cond_fail %13 : $Builtin.Int1 // id: %14
%15 = apply %10() : $@convention(thin) () -> ()
%16 = integer_literal $Builtin.Int64, 3 // user: %17
%17 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %16 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %18
%18 = tuple_extract %17 : $(Builtin.Int64, Builtin.Int1), 1 // user: %19
cond_fail %13 : $Builtin.Int1 // id: %19
%20 = apply %10() : $@convention(thin) () -> ()
br bb2 // id: %21
bb2: // Preds: bb0 bb1
%22 = tuple () // user: %23
return %22 : $() // id: %23
}
// CHECK-LABEL: @sub_unsigned_branch_cond
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @sub_unsigned_branch_cond : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, 2 // users: %3, %12
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %3, %7, %12, %17
%3 = builtin "cmp_ult_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb2, bb1 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 1 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // users: %7, %12, %17
%7 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
cond_fail %8 : $Builtin.Int1 // id: %9
%10 = function_ref @sink_signed_int : $@convention(thin) () -> () // users: %11, %15, %20
%11 = apply %10() : $@convention(thin) () -> ()
%12 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
cond_fail %13 : $Builtin.Int1 // id: %14
%15 = apply %10() : $@convention(thin) () -> ()
%16 = integer_literal $Builtin.Int64, 3 // user: %17
%17 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %16 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %18
%18 = tuple_extract %17 : $(Builtin.Int64, Builtin.Int1), 1 // user: %19
cond_fail %13 : $Builtin.Int1 // id: %19
%20 = apply %10() : $@convention(thin) () -> ()
br bb2 // id: %21
bb2: // Preds: bb0 bb1
%22 = tuple () // user: %23
return %22 : $() // id: %23
}
// CHECK-LABEL: @sub_unsigned_branch_cond2
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @sub_unsigned_branch_cond2 : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, 2 // users: %3, %12
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %3, %7, %12, %17
%3 = builtin "cmp_uge_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb1, bb2 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 1 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // users: %7, %12, %17
%7 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
cond_fail %8 : $Builtin.Int1 // id: %9
%10 = function_ref @sink_signed_int : $@convention(thin) () -> () // users: %11, %15, %20
%11 = apply %10() : $@convention(thin) () -> ()
%12 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
cond_fail %13 : $Builtin.Int1 // id: %14
%15 = apply %10() : $@convention(thin) () -> ()
%16 = integer_literal $Builtin.Int64, 3 // user: %17
%17 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %16 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %18
%18 = tuple_extract %17 : $(Builtin.Int64, Builtin.Int1), 1 // user: %19
cond_fail %13 : $Builtin.Int1 // id: %19
%20 = apply %10() : $@convention(thin) () -> ()
br bb2 // id: %21
bb2: // Preds: bb0 bb1
%22 = tuple () // user: %23
return %22 : $() // id: %23
}
// CHECK-LABEL: @unsigned_sub_previous_traps
// Keep the first cond-fail
// CHECK: cond_fail
// Keep the condfail with +10 because it is not guarded by the first condfail (+9)
// CHECK: cond_fail
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @unsigned_sub_previous_traps : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = function_ref @sink_signed_int : $@convention(thin) () -> () // users: %8, %13, %18, %23, %28, %29
%8 = apply %7() : $@convention(thin) () -> ()
%9 = integer_literal $Builtin.Int64, 2 // user: %10
%10 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %9 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%11 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
cond_fail %11 : $Builtin.Int1 // id: %12
%13 = apply %7() : $@convention(thin) () -> ()
%14 = integer_literal $Builtin.Int64, 3 // user: %15
%15 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %14 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %16
%16 = tuple_extract %15 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
cond_fail %16 : $Builtin.Int1 // id: %17
%18 = apply %7() : $@convention(thin) () -> ()
%19 = integer_literal $Builtin.Int64, 5 // user: %20
%20 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %19 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %21
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 1 // user: %22
cond_fail %21 : $Builtin.Int1 // id: %22
%23 = apply %7() : $@convention(thin) () -> ()
%24 = integer_literal $Builtin.Int64, 10 // user: %25
%25 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %24 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %26
%26 = tuple_extract %25 : $(Builtin.Int64, Builtin.Int1), 1 // user: %27
cond_fail %26 : $Builtin.Int1 // id: %27
%28 = apply %7() : $@convention(thin) () -> ()
%29 = apply %7() : $@convention(thin) () -> ()
%30 = tuple () // user: %31
return %30 : $() // id: %31
}
// CHECK-LABEL: @signed_sub_previous_traps
sil hidden @signed_sub_previous_traps : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
// Keep this condfail because it is the first one.
// CHECK: cond_fail
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = function_ref @sink_unsigned_int : $@convention(thin) () -> () // users: %8, %13, %18, %23, %28, %29
%8 = apply %7() : $@convention(thin) () -> ()
%9 = integer_literal $Builtin.Int64, 2 // user: %10
%10 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %9 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%11 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
cond_fail %11 : $Builtin.Int1 // id: %12
%13 = apply %7() : $@convention(thin) () -> ()
%14 = integer_literal $Builtin.Int64, 3 // user: %15
%15 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %14 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %16
%16 = tuple_extract %15 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
cond_fail %16 : $Builtin.Int1 // id: %17
%18 = apply %7() : $@convention(thin) () -> ()
%19 = integer_literal $Builtin.Int64, 5 // user: %20
%20 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %19 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %21
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 1 // user: %22
cond_fail %21 : $Builtin.Int1 // id: %22
%23 = apply %7() : $@convention(thin) () -> ()
%24 = integer_literal $Builtin.Int64, 10 // user: %25
%25 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %24 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %26
%26 = tuple_extract %25 : $(Builtin.Int64, Builtin.Int1), 1 // user: %27
// Keep this condfail because it is not in the guarded range.
// CHECK: cond_fail
cond_fail %26 : $Builtin.Int1 // id: %27
%28 = apply %7() : $@convention(thin) () -> ()
%29 = apply %7() : $@convention(thin) () -> ()
%30 = tuple () // user: %31
// CHECK-NOT: cond_fail
// CHECK: return
return %30 : $() // id: %31
}
// CHECK-LABEL: @unsigned_add_previous_traps
sil hidden @unsigned_add_previous_traps : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
// Keep the first condfail.
//CHECK: cond_fail
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = function_ref @sink_signed_int : $@convention(thin) () -> () // users: %8, %13, %18, %23, %28, %29
%8 = apply %7() : $@convention(thin) () -> ()
%9 = integer_literal $Builtin.Int64, 2 // user: %10
%10 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %9 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%11 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
cond_fail %11 : $Builtin.Int1 // id: %12
%13 = apply %7() : $@convention(thin) () -> ()
%14 = integer_literal $Builtin.Int64, 3 // user: %15
%15 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %14 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %16
%16 = tuple_extract %15 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
cond_fail %16 : $Builtin.Int1 // id: %17
%18 = apply %7() : $@convention(thin) () -> ()
%19 = integer_literal $Builtin.Int64, 5 // user: %20
%20 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %19 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %21
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 1 // user: %22
cond_fail %21 : $Builtin.Int1 // id: %22
%23 = apply %7() : $@convention(thin) () -> ()
%24 = integer_literal $Builtin.Int64, 10 // user: %25
%25 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %24 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %26
%26 = tuple_extract %25 : $(Builtin.Int64, Builtin.Int1), 1 // user: %27
// Keep the out-of-range condfail.
//CHECK: cond_fail
cond_fail %26 : $Builtin.Int1 // id: %27
%28 = apply %7() : $@convention(thin) () -> ()
%29 = apply %7() : $@convention(thin) () -> ()
%30 = tuple () // user: %31
// CHECK-NOT: cond_fail
// CHECK: return
return %30 : $() // id: %31
}
// CHECK-LABEL: @signed_add_previous_traps
// Keep the first condfail
// CHECK: cond_fail
// Keep out-of-range condfail
// CHECK: cond_fail
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_add_previous_traps : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = function_ref @sink_unsigned_int : $@convention(thin) () -> () // users: %8, %13, %18, %23, %28, %29
%8 = apply %7() : $@convention(thin) () -> ()
%9 = integer_literal $Builtin.Int64, 2 // user: %10
%10 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %9 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%11 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
cond_fail %11 : $Builtin.Int1 // id: %12
%13 = apply %7() : $@convention(thin) () -> ()
%14 = integer_literal $Builtin.Int64, 3 // user: %15
%15 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %14 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %16
%16 = tuple_extract %15 : $(Builtin.Int64, Builtin.Int1), 1 // user: %17
cond_fail %16 : $Builtin.Int1 // id: %17
%18 = apply %7() : $@convention(thin) () -> ()
%19 = integer_literal $Builtin.Int64, 5 // user: %20
%20 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %19 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %21
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 1 // user: %22
cond_fail %21 : $Builtin.Int1 // id: %22
%23 = apply %7() : $@convention(thin) () -> ()
%24 = integer_literal $Builtin.Int64, 10 // user: %25
%25 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %24 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %26
%26 = tuple_extract %25 : $(Builtin.Int64, Builtin.Int1), 1 // user: %27
cond_fail %26 : $Builtin.Int1 // id: %27
%28 = apply %7() : $@convention(thin) () -> ()
%29 = apply %7() : $@convention(thin) () -> ()
%30 = tuple () // user: %31
return %30 : $() // id: %31
}
// CHECK-LABEL: @add1_signed_branch
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @add1_signed_branch : $@convention(thin) (Int64, Int64) -> () {
bb0(%0 : $Int64, %1 : $Int64):
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %8, %14
%3 = struct_extract %1 : $Int64, #Int64._value // user: %4
%4 = builtin "cmp_slt_Int64"(%2 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int1 // user: %5
cond_br %4, bb1, bb2 // id: %5
bb1: // Preds: bb0
%6 = integer_literal $Builtin.Int64, 1 // user: %8
%7 = integer_literal $Builtin.Int1, -1 // users: %8, %14
%8 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %9
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %10
cond_fail %9 : $Builtin.Int1 // id: %10
%11 = function_ref @sink_unsigned_int : $@convention(thin) () -> () // users: %12, %17
%12 = apply %11() : $@convention(thin) () -> ()
%13 = integer_literal $Builtin.Int64, 2 // user: %14
%14 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %13 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %15
%15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 1 // user: %16
cond_fail %9 : $Builtin.Int1 // id: %16
%17 = apply %11() : $@convention(thin) () -> ()
br bb2 // id: %18
bb2: // Preds: bb0 bb1
%19 = tuple () // user: %20
return %19 : $() // id: %20
}
// CHECK-LABEL: @add1_unsigned_branch
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @add1_unsigned_branch : $@convention(thin) (UInt64, UInt64) -> () {
bb0(%0 : $UInt64, %1 : $UInt64):
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %4, %8, %14
%3 = struct_extract %1 : $UInt64, #UInt64._value // user: %4
%4 = builtin "cmp_ult_Int64"(%2 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int1 // user: %5
cond_br %4, bb1, bb2 // id: %5
bb1: // Preds: bb0
%6 = integer_literal $Builtin.Int64, 1 // user: %8
%7 = integer_literal $Builtin.Int1, -1 // users: %8, %14
%8 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %9
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %10
cond_fail %9 : $Builtin.Int1 // id: %10
%11 = function_ref @sink_signed_int : $@convention(thin) () -> () // users: %12, %17
%12 = apply %11() : $@convention(thin) () -> ()
%13 = integer_literal $Builtin.Int64, 2 // user: %14
%14 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %13 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %15
%15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 1 // user: %16
cond_fail %9 : $Builtin.Int1 // id: %16
%17 = apply %11() : $@convention(thin) () -> ()
br bb2 // id: %18
bb2: // Preds: bb0 bb1
%19 = tuple () // user: %20
return %19 : $() // id: %20
}
// CHECK-LABEL: @remove_past_checks
sil hidden @remove_past_checks : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 1 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %8, %12, %16, %20
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %8, %12, %16, %20
// CHECK: sadd_with_overflow_Int64
%4 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
// CHECK-NOT: cond_fail
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, 2 // user: %8
// CHECK: sadd_with_overflow_Int64
%8 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %7 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %9
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %10
// CHECK-NOT: cond_fail
cond_fail %9 : $Builtin.Int1 // id: %10
%11 = integer_literal $Builtin.Int64, 3 // user: %12
// CHECK: sadd_with_overflow_Int64
%12 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %11 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
// CHECK-NOT: cond_fail
cond_fail %13 : $Builtin.Int1 // id: %14
%15 = integer_literal $Builtin.Int64, 4 // user: %16
// CHECK: sadd_with_overflow_Int64
%16 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %15 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %17
%17 = tuple_extract %16 : $(Builtin.Int64, Builtin.Int1), 1 // user: %18
// CHECK-NOT: cond_fail
cond_fail %17 : $Builtin.Int1 // id: %18
%19 = integer_literal $Builtin.Int64, 5 // user: %20
// CHECK: sadd_with_overflow_Int64
%20 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %19 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %21
%21 = tuple_extract %20 : $(Builtin.Int64, Builtin.Int1), 1 // user: %22
// We keep the last cond-fail, which is enough to guard all the others.
// CHECK: cond_fail
cond_fail %21 : $Builtin.Int1 // id: %22
%23 = tuple () // user: %24
// CHECK: return
return %23 : $() // id: %24
}
// Make sure we are not crashing on this one (and that we are not removing the condfails)
// This comes from the following test:
//func foo(x : Int64, y : Int8) {
// 3 + x
// 2 + y
//}
// CHECK-LABEL: @bitwidth_crash
// CHECK: cond_fail
// CHECK: cond_fail
// CHECK: return
sil hidden @bitwidth_crash : $@convention(thin) (Int64, Int8) -> () {
bb0(%0 : $Int64, %1 : $Int8):
%2 = integer_literal $Builtin.Int64, 3 // user: %5
%3 = struct_extract %0 : $Int64, #Int64._value // user: %5
%4 = integer_literal $Builtin.Int1, -1 // users: %5, %10
%5 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %3 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %6
%6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 1 // user: %7
cond_fail %6 : $Builtin.Int1 // id: %7
%8 = integer_literal $Builtin.Int8, 2 // user: %10
%9 = struct_extract %1 : $Int8, #Int8._value // user: %10
%10 = builtin "sadd_with_overflow_Int8"(%8 : $Builtin.Int8, %9 : $Builtin.Int8, %4 : $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1) // user: %11
%11 = tuple_extract %10 : $(Builtin.Int8, Builtin.Int1), 1 // user: %12
cond_fail %11 : $Builtin.Int1 // id: %12
%13 = tuple () // user: %14
return %13 : $() // id: %14
}
// CHECK-LABEL: @signed_cmpeq_sub
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_cmpeq_sub : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 3 // users: %3, %12
%2 = struct_extract %0 : $Int64, #Int64._value // users: %3, %7, %12
%3 = builtin "cmp_ne_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb1, bb2 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 999 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // user: %7
%7 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
%9 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
br bb3 // id: %10
bb2: // Preds: bb0
%11 = integer_literal $Builtin.Int1, -1 // user: %12
%12 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %11 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
cond_fail %13 : $Builtin.Int1 // id: %14
br bb3 // id: %15
bb3: // Preds: bb1 bb2
%16 = tuple () // user: %17
return %16 : $() // id: %17
}
// CHECK-LABEL: @unsigned_cmpeq_sub
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @unsigned_cmpeq_sub : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, 3 // users: %3, %12
%2 = struct_extract %0 : $UInt64, #UInt64._value // users: %3, %7, %12
%3 = builtin "cmp_ne_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 // user: %4
cond_br %3, bb1, bb2 // id: %4
bb1: // Preds: bb0
%5 = integer_literal $Builtin.Int64, 999 // user: %7
%6 = integer_literal $Builtin.Int1, -1 // user: %7
%7 = builtin "uadd_with_overflow_Int64"(%2 : $Builtin.Int64, %5 : $Builtin.Int64, %6 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %8
%8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
%9 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 1 // user: %9
br bb3 // id: %10
bb2: // Preds: bb0
%11 = integer_literal $Builtin.Int1, -1 // user: %12
%12 = builtin "usub_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %11 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %13
%13 = tuple_extract %12 : $(Builtin.Int64, Builtin.Int1), 1 // user: %14
cond_fail %13 : $Builtin.Int1 // id: %14
br bb3 // id: %15
bb3: // Preds: bb1 bb2
%16 = tuple () // user: %17
return %16 : $() // id: %17
}
// CHECK-LABEL: @signed_mul_previous_traps
// Keep the first condfail but remove the second one.
// CHECK: cond_fail
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_mul_previous_traps : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, 2
%8 = builtin "smul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// We can remove this check.
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @unsigned_mul_previous_traps
// Keep the first condfail but remove the second one.
// CHECK: umul_with_overflow_Int64
// CHECK: cond_fail
// CHECK: umul_with_overflow_Int64
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @unsigned_mul_previous_traps : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
%4 = builtin "umul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, 2
%8 = builtin "umul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// We can remove this check.
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @signed_mul_previous_traps_neg
// CHECK: smul_with_overflow_Int64
// CHECK: smul_with_overflow_Int64
// Make sure we keep the last overflow check.
// CHECK: cond_fail
// CHECK: return
sil hidden @signed_mul_previous_traps_neg : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 9 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
// This is X * 9
// We can remove this check because the following check will guard us: abs(-100) > abs(9).
%4 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, -100
%8 = builtin "smul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// This is -100 * X. We can't remove this check because abs(-100) > abs(9).
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @signed_mul_previous_traps_abs_neg
// CHECK: smul_with_overflow_Int64
// CHECK: cond_fail
// CHECK: smul_with_overflow_Int64
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_mul_previous_traps_abs_neg : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 1000 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
// This is X * 9
%4 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, -100
%8 = builtin "smul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// This is -100 * X. We can remove this check because abs(-100) < abs(1000).
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @signed_mul_previous_traps_abs_neg2
// CHECK: smul_with_overflow_Int64
// CHECK: cond_fail
// CHECK: smul_with_overflow_Int64
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_mul_previous_traps_abs_neg2 : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 1000 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
// This is X * 9
%4 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, -100
%8 = builtin "smul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// This is -100 * X. We can remove this check because abs(-100) < abs(1000).
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @signed_mul_traps_min_int
// CHECK: smul_with_overflow_Int64
// CHECK: cond_fail
// CHECK: smul_with_overflow_Int64
// CHECK: cond_fail
// CHECK: return
sil hidden @signed_mul_traps_min_int : $@convention(thin) (Int64) -> () {
bb0(%0 : $Int64):
%1 = integer_literal $Builtin.Int64, 1 // user: %4
%2 = struct_extract %0 : $Int64, #Int64._value // users: %4, %10, %15, %20, %25
%3 = integer_literal $Builtin.Int1, -1 // users: %4, %10, %15, %20, %25
// This is X * 9
%4 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %5
%5 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 1 // user: %6
cond_fail %5 : $Builtin.Int1 // id: %6
%7 = integer_literal $Builtin.Int64, -1
%8 = builtin "smul_with_overflow_Int64"(%7 : $Builtin.Int64, %2 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12
// This is -1 * X. We can remove this check because X could be MIN_INT, and the result will overflow.
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @signed_min_int_comparison
// CHECK: smul_with_overflow_Int8
// CHECK: cond_fail
// CHECK: smul_with_overflow_Int8
// CHECK-NOT: cond_fail
// CHECK: return
sil hidden @signed_min_int_comparison : $@convention(thin) (Int8) -> () {
bb0(%0 : $Int8):
%1 = integer_literal $Builtin.Int8, -128
%2 = struct_extract %0 : $Int8, #Int8._value
%3 = integer_literal $Builtin.Int1, -1
%4 = builtin "smul_with_overflow_Int8"(%2 : $Builtin.Int8, %1 : $Builtin.Int8, %3 : $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1)
%5 = tuple_extract %4 : $(Builtin.Int8, Builtin.Int1), 1
cond_fail %5 : $Builtin.Int1
%7 = integer_literal $Builtin.Int8, 127
%8 = builtin "smul_with_overflow_Int8"(%2 : $Builtin.Int8, %7 : $Builtin.Int8, %3 : $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1) // user: %11
%9 = tuple_extract %8 : $(Builtin.Int8, Builtin.Int1), 1 // user: %12
cond_fail %9 : $Builtin.Int1
%10 = tuple ()
return %10 : $()
}
// CHECK-LABEL: @crash_unary_comparator
// CHECK: return
sil hidden @crash_unary_comparator : $@convention(thin) (Builtin.Int32) -> () {
bb0(%0 : $Builtin.Int32):
%1 = builtin "trunc_Int32_Int1"(%0 : $Builtin.Int32) : $Builtin.Int1
cond_br %1, bb1, bb2 // id: %4
bb1: // Preds: bb0
br bb3 // id: %10
bb2: // Preds: bb0
br bb3 // id: %15
bb3: // Preds: bb1 bb2
%3 = tuple () // user: %17
return %3 : $() // id: %17
}
// Check that we are not crashing on arithmetic of different kinds
// that makes formulas of different types.
sil hidden @mixed_types : $@convention(thin) (Int8) -> () {
bb0(%0 : $Int8):
%1 = integer_literal $Builtin.Int8, -128
%2 = struct_extract %0 : $Int8, #Int8._value
%3 = integer_literal $Builtin.Int1, -1
%4 = builtin "smul_with_overflow_Int8"(%2 : $Builtin.Int8, %1 : $Builtin.Int8, %3 : $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1)
%5 = tuple_extract %4 : $(Builtin.Int8, Builtin.Int1), 1
cond_fail %5 : $Builtin.Int1
%v0 = integer_literal $Builtin.Int32, 128
%v1 = integer_literal $Builtin.Int32, 128
%v4 = builtin "smul_with_overflow_Int32"(%v1 : $Builtin.Int32, %v0 : $Builtin.Int32, %3 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
%v5 = tuple_extract %v4 : $(Builtin.Int32, Builtin.Int1), 1
cond_fail %v5 : $Builtin.Int1
%g0 = integer_literal $Builtin.Int64, 2
%g1 = integer_literal $Builtin.Int64, 1
%g3 = builtin "cmp_slt_Int64"(%g0 : $Builtin.Int64, %g1 : $Builtin.Int64) : $Builtin.Int1
cond_fail %g3 : $Builtin.Int1
%t0 = integer_literal $Builtin.Int32, 2
%t1 = integer_literal $Builtin.Int32, 1
%t3 = builtin "cmp_slt_Int32"(%t0 : $Builtin.Int32, %t1 : $Builtin.Int32) : $Builtin.Int1
cond_fail %t3 : $Builtin.Int1
%ret = tuple ()
return %ret : $()
}
// Check that the optimization can handle even patterns like this:
// %cmp_result = builtin "cmp_ult_Int64"(%x : $Builtin.Int64, %y : $Builtin.Int64) : $Builtin.Int1
// This cond_fail formula should be registered!
// cond_fail %cmp_result : $Builtin.Int1
// At this point we know that x >= y
// %usub_result = builtin "usub_with_overflow_Int64"(%x : $Builtin.Int64, %y : $Builtin.Int64, %check_overfow : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
// %usub_val = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 0
// We can figure out that x - y will not underflow because of x >= y
// %usub_underverflow = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 1
// cond_fail %usub_underflow : $Builtin.Int1
// CHECK-LABEL: sil @cond_fail_of_cmp
// CHECK: cond_fail
// Second cond_fail should be removed, because it never fails.
// CHECK-NOT: cond_fail
// CHECK: // end sil function 'cond_fail_of_cmp'
sil @cond_fail_of_cmp : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () {
bb0(%x : $Builtin.Int64, %y: $Builtin.Int64):
%cmp_result = builtin "cmp_ult_Int64"(%x : $Builtin.Int64, %y : $Builtin.Int64) : $Builtin.Int1
// This cond_fail formula should be registered!
cond_fail %cmp_result : $Builtin.Int1
%check_overflow = integer_literal $Builtin.Int1, -1
// At this point we know that x >= y
%usub_result = builtin "usub_with_overflow_Int64"(%x : $Builtin.Int64, %y : $Builtin.Int64, %check_overflow : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%usub_val = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 0
// We can figure out that x - y will not underflow because of x >= y
%usub_underflow = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %usub_underflow : $Builtin.Int1
%ret = tuple ()
return %ret : $()
} // end sil function 'cond_fail_of_cmp'