mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* `sitofp` signed integer to floating point * `rint` round floating point to integral * `bitcast` between integer and floating point Constant folding `bitcast`s also made it necessary to rewrite constant folding for Nan and inf values, because the old code explicitly checked for `bitcast` intrinsics. Relying on constant folded `bitcast`s makes the new version much simpler. It is important to constant fold these intrinsics already in SIL because it enables other optimizations.
1645 lines
76 KiB
Plaintext
1645 lines
76 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -diagnostic-constant-propagation | %FileCheck %s
|
|
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -performance-constant-propagation | %FileCheck %s
|
|
|
|
import Swift
|
|
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
|
|
}
|
|
|
|
sil @count_leading_zeros_corner_case : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%zero64 = integer_literal $Builtin.Int64, 0
|
|
%zero1 = integer_literal $Builtin.Int1, 0
|
|
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
|
|
return %ctlz : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @count_leading_zeros_corner_case
|
|
// CHECK-NOT: integer_literal $Builtin.Int64, 0
|
|
// CHECK-NOT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NOT: builtin
|
|
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 64
|
|
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
|
|
}
|
|
|
|
sil @count_leading_zeros : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%zero64 = integer_literal $Builtin.Int64, 2
|
|
%zero1 = integer_literal $Builtin.Int1, 0
|
|
%ctlz = builtin "int_ctlz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
|
|
return %ctlz : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @count_leading_zeros
|
|
// CHECK-NOT: integer_literal $Builtin.Int64, 2
|
|
// CHECK-NOT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NOT: builtin
|
|
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 62
|
|
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
|
|
}
|
|
|
|
sil @count_trailing_zeros_corner_case : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%zero64 = integer_literal $Builtin.Int64, 0
|
|
%zero1 = integer_literal $Builtin.Int1, 0
|
|
%cttz = builtin "int_cttz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
|
|
return %cttz : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @count_trailing_zeros_corner_case
|
|
// CHECK-NOT: integer_literal $Builtin.Int64, 0
|
|
// CHECK-NOT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NOT: builtin
|
|
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 64
|
|
// CHECK-NEXT: return [[RES]] : $Builtin.Int64
|
|
}
|
|
|
|
sil @count_trailing_zeros : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%zero64 = integer_literal $Builtin.Int64, 2
|
|
%zero1 = integer_literal $Builtin.Int1, 0
|
|
%cttz = builtin "int_cttz_Int64"(%zero64 : $Builtin.Int64, %zero1 : $Builtin.Int1) : $Builtin.Int64
|
|
return %cttz : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @count_trailing_zeros
|
|
// CHECK-NOT: integer_literal $Builtin.Int64, 2
|
|
// CHECK-NOT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NOT: builtin
|
|
// CHECK: [[RES:%.*]] = integer_literal $Builtin.Int64, 1
|
|
// CHECK-NEXT: return [[RES]] : $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
|
|
}
|
|
|
|
// Compute an expression using a chain of arithmetic with non-overflowing instructions: 2 * (2 + 3) - 3
|
|
sil @fold_arithmetic_without_overflow : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 2
|
|
%110 = integer_literal $Builtin.Int64, 3
|
|
%19 = builtin "add_Int64"(%0 : $Builtin.Int64, %110 : $Builtin.Int64) : $Builtin.Int64
|
|
%21 = builtin "mul_Int64"(%0 : $Builtin.Int64, %19 : $Builtin.Int64) : $Builtin.Int64
|
|
%23 = builtin "sub_Int64"(%21 : $Builtin.Int64, %110 : $Builtin.Int64) : $Builtin.Int64
|
|
return %23 : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @fold_arithmetic_without_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 @testFoldingNonNegativeSignedInt : $@convention(thin) (Builtin.Int64) -> () {
|
|
bb0(%0 : $Builtin.Int64):
|
|
%zero = integer_literal $Builtin.Int64, 0
|
|
%non_neg = builtin "assumeNonNegative_Int64"(%0 : $Builtin.Int64) : $Builtin.Int64
|
|
%compare_slt = builtin "cmp_slt_Int64"(%non_neg : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sgt = builtin "cmp_sgt_Int64"(%zero : $Builtin.Int64, %non_neg : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sge = builtin "cmp_sge_Int64"(%non_neg : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sle = builtin "cmp_sle_Int64"(%zero : $Builtin.Int64, %non_neg : $Builtin.Int64) : $Builtin.Int1
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
// CHECK-LABEL: sil @testFoldingNonNegativeSignedInt
|
|
// CHECK: bb
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: return
|
|
}
|
|
|
|
sil @testFoldingIntBinaryPredicates : $@convention(thin) (Builtin.Int32) -> () {
|
|
bb0(%0 : $Builtin.Int32):
|
|
%1 = integer_literal $Builtin.Int1, 1
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
// This is Int32.Max
|
|
%3 = integer_literal $Builtin.Int32, 2147483647
|
|
%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
|
|
%17 = builtin "cmp_ult_Int32"(%12 : $Builtin.Int32, %11 : $Builtin.Int32) : $Builtin.Int1
|
|
// Int32.Max < x
|
|
%18 = builtin "cmp_slt_Int32"(%3 : $Builtin.Int32, %0 : $Builtin.Int32) : $Builtin.Int1
|
|
// x > Int32.Max
|
|
%19 = builtin "cmp_sgt_Int32"(%0 : $Builtin.Int32, %3 : $Builtin.Int32) : $Builtin.Int1
|
|
// Int32.Max >= x
|
|
%20 = builtin "cmp_sge_Int32"(%3 : $Builtin.Int32, %0 : $Builtin.Int32) : $Builtin.Int1
|
|
// x <= Int32.Max
|
|
%21 = builtin "cmp_sle_Int32"(%0 : $Builtin.Int32, %3 : $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: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: return
|
|
}
|
|
|
|
sil @testFoldingUnsignedIntComparisons : $@convention(thin) (Builtin.Int32) -> () {
|
|
bb0(%0 : $Builtin.Int32):
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
%3 = integer_literal $Builtin.Int32, 0
|
|
// unsigned value is never less then 0
|
|
%18 = builtin "cmp_ult_Int32"(%0 : $Builtin.Int32, %3 : $Builtin.Int32) : $Builtin.Int1
|
|
// unsigned value is always >= 0
|
|
%19 = builtin "cmp_uge_Int32"(%0 : $Builtin.Int32, %3 : $Builtin.Int32) : $Builtin.Int1
|
|
// 0 is always <= an unsigned value
|
|
%20 = builtin "cmp_ule_Int32"(%3 : $Builtin.Int32, %0 : $Builtin.Int32) : $Builtin.Int1
|
|
// 0 is never greater than an unsigned value
|
|
%21 = builtin "cmp_ugt_Int32"(%3 : $Builtin.Int32, %0 : $Builtin.Int32) : $Builtin.Int1
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
// CHECK-LABEL: sil @testFoldingUnsignedIntComparisons
|
|
// CHECK: bb0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// 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
|
|
}
|
|
|
|
// For any x of the same size as Int.max and n>=1 , (x>>n) is always <= Int.max,
|
|
// that is (x>>n) <= Int.max and Int.max >= (x>>n) are true.
|
|
// At the same time (x>>n) > Int.max and Int.max < (x>>n) is always false.
|
|
sil @fold_cmp_lshr_with_IntMax : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64):
|
|
%1 = integer_literal $Builtin.Int64, 9223372036854775807
|
|
%2 = integer_literal $Builtin.Int64, 1
|
|
%3 = integer_literal $Builtin.Int64, 3
|
|
%4 = integer_literal $Builtin.Int64, 0
|
|
%5 = integer_literal $Builtin.Int64, -2
|
|
|
|
// x >> 1
|
|
%9 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
|
|
|
|
%10 = builtin "cmp_sge_Int64"(%1 : $Builtin.Int64, %9 : $Builtin.Int64) : $Builtin.Int1
|
|
%11 = builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %9 : $Builtin.Int64) : $Builtin.Int1
|
|
%12 = builtin "cmp_sle_Int64"(%9 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%13 = builtin "cmp_ule_Int64"(%9 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
%20 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %9 : $Builtin.Int64) : $Builtin.Int1
|
|
%21 = builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %9 : $Builtin.Int64) : $Builtin.Int1
|
|
%22 = builtin "cmp_sgt_Int64"(%9 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%23 = builtin "cmp_ugt_Int64"(%9 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
// x >> 3
|
|
%29 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int64
|
|
|
|
%30 = builtin "cmp_sge_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
%31 = builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
%32 = builtin "cmp_sle_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%33 = builtin "cmp_ule_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
%40 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
%41 = builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
%42 = builtin "cmp_sgt_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%43 = builtin "cmp_ugt_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
// Check that this peephole does not happen if the shift amount is < 1
|
|
|
|
// x >> 0 (i.e. x shifted by something < 1)
|
|
%59 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %4 : $Builtin.Int64) : $Builtin.Int64
|
|
|
|
%60 = builtin "cmp_sge_Int64"(%1 : $Builtin.Int64, %59 : $Builtin.Int64) : $Builtin.Int1
|
|
%61 = builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %59 : $Builtin.Int64) : $Builtin.Int1
|
|
%62 = builtin "cmp_sle_Int64"(%59 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%63 = builtin "cmp_ule_Int64"(%59 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
%70 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %59 : $Builtin.Int64) : $Builtin.Int1
|
|
%71 = builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %59 : $Builtin.Int64) : $Builtin.Int1
|
|
%72 = builtin "cmp_sgt_Int64"(%59 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%73 = builtin "cmp_ugt_Int64"(%59 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
// x >> -2 (i.e. x shifted by something < 1)
|
|
%79 = builtin "lshr_Int64"(%0 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int64
|
|
|
|
%80 = builtin "cmp_sge_Int64"(%1 : $Builtin.Int64, %79 : $Builtin.Int64) : $Builtin.Int1
|
|
%81 = builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %79 : $Builtin.Int64) : $Builtin.Int1
|
|
%82 = builtin "cmp_sle_Int64"(%79 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%83 = builtin "cmp_ule_Int64"(%79 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
%90 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %79 : $Builtin.Int64) : $Builtin.Int1
|
|
%91 = builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %79 : $Builtin.Int64) : $Builtin.Int1
|
|
%92 = builtin "cmp_sgt_Int64"(%79 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
%93 = builtin "cmp_ugt_Int64"(%79 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
return %4 : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @fold_cmp_lshr_with_IntMax
|
|
// CHECK: bb0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int64, 9223372036854775807
|
|
// CHECK-NEXT: integer_literal $Builtin.Int64, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int64, -2
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: builtin "lshr_Int64"(%0 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int64
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %20 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: builtin "cmp_ule_Int64"(%20 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %20 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: builtin "cmp_ugt_Int64"(%20 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: builtin "lshr_Int64"(%0 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int64
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: builtin "cmp_uge_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: builtin "cmp_ule_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: builtin "cmp_ult_Int64"(%1 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
// CHECK-NEXT: integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: builtin "cmp_ugt_Int64"(%29 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1
|
|
// 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
|
|
}
|
|
|
|
sil @dont_fold_unsigned_op_with_overflow_lt_zero : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64, %1 : $Builtin.Int64):
|
|
%zero = integer_literal $Builtin.Int64, 0
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
|
|
%uadd_result = builtin "uadd_with_overflow_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2: $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%uadd_with_overflow_result = tuple_extract %uadd_result : $(Builtin.Int64, Builtin.Int1), 0
|
|
%uadd_overflow = tuple_extract %uadd_result : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %uadd_overflow : $Builtin.Int1
|
|
%compare_slt_uadd_result = builtin "cmp_slt_Int64"(%uadd_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sge_uadd_result = builtin "cmp_sge_Int64"(%uadd_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
|
|
%usub_result = builtin "usub_with_overflow_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2: $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%usub_with_overflow_result = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 0
|
|
%usub_overflow = tuple_extract %usub_result : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %uadd_overflow : $Builtin.Int1
|
|
%compare_slt_usub_result = builtin "cmp_slt_Int64"(%usub_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sge_usub_result = builtin "cmp_sge_Int64"(%usub_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
|
|
%umul_result = builtin "umul_with_overflow_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2: $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%umul_with_overflow_result = tuple_extract %umul_result : $(Builtin.Int64, Builtin.Int1), 0
|
|
%umul_overflow = tuple_extract %umul_result : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %umul_overflow : $Builtin.Int1
|
|
%compare_slt_umul_result = builtin "cmp_slt_Int64"(%umul_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
%compare_sge_umul_result = builtin "cmp_sge_Int64"(%umul_with_overflow_result : $Builtin.Int64, %zero : $Builtin.Int64) : $Builtin.Int1
|
|
|
|
return %uadd_with_overflow_result : $Builtin.Int64
|
|
|
|
// CHECK-LABEL: sil @dont_fold_unsigned_op_with_overflow_lt_zero
|
|
// CHECK: builtin "uadd_with_overflow_Int64"
|
|
// CHECK-NOT: integer_literal
|
|
// CHECK: } // end sil function 'dont_fold_unsigned_op_with_overflow_lt_zero'
|
|
}
|
|
|
|
// fold float comparison operations involving literals only
|
|
sil @fold_literal_float_comparison : $@convention(thin) () -> () {
|
|
%0 = float_literal $Builtin.FPIEEE32, 0x3F800000 // 1
|
|
%1 = float_literal $Builtin.FPIEEE32, 0x40000000 // 2
|
|
|
|
// Ordered
|
|
%3 = builtin "fcmp_oeq_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%4 = builtin "fcmp_ogt_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%8 = builtin "fcmp_one_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%9 = builtin "fcmp_ord_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%11 = builtin "fcmp_ueq_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%12 = builtin "fcmp_ugt_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%16 = builtin "fcmp_une_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%17 = builtin "fcmp_uno_FPIEEE32"(%0 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL:sil @fold_literal_float_comparison
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %14 = tuple ()
|
|
// CHECK-NEXT: return %14 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_literal_float_comparison'
|
|
}
|
|
|
|
// fold float comparison operations with NaN
|
|
sil @fold_float_comparison_with_nan : $@convention(thin) () -> () {
|
|
%1 = float_literal $Builtin.FPIEEE32, 0x3F800000 // 1
|
|
%900 = integer_literal $Builtin.Int32, 2143289344 // user: %3
|
|
%909 = builtin "bitcast_Int32_FPIEEE32"(%900 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
|
|
// Ordered
|
|
%3 = builtin "fcmp_oeq_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%4 = builtin "fcmp_ogt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%8 = builtin "fcmp_one_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%31 = builtin "fcmp_oeq_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%41 = builtin "fcmp_ogt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%51 = builtin "fcmp_oge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%61 = builtin "fcmp_olt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%71 = builtin "fcmp_ole_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%81 = builtin "fcmp_one_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%11 = builtin "fcmp_ueq_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%12 = builtin "fcmp_ugt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%16 = builtin "fcmp_une_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%111 = builtin "fcmp_ueq_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%121 = builtin "fcmp_ugt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%131 = builtin "fcmp_uge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%141 = builtin "fcmp_ult_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%151 = builtin "fcmp_ule_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%161 = builtin "fcmp_une_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL:sil @fold_float_comparison_with_nan
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %14 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %15 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %16 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %17 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %18 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %19 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %20 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %21 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %22 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %23 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %24 = tuple ()
|
|
// CHECK-NEXT: return %24 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_float_comparison_with_nan'
|
|
}
|
|
|
|
// fold float comparison operations with Infinity
|
|
sil @fold_float_comparison_with_inf : $@convention(thin) () -> () {
|
|
%1 = float_literal $Builtin.FPIEEE32, 0x3F800000 // 1
|
|
|
|
%900 = integer_literal $Builtin.Int32, 2139095040 // user: %4
|
|
%909 = builtin "bitcast_Int32_FPIEEE32"(%900 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
|
|
// Ordered
|
|
%4 = builtin "fcmp_ogt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%41 = builtin "fcmp_ogt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%51 = builtin "fcmp_oge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%61 = builtin "fcmp_olt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%71 = builtin "fcmp_ole_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%12 = builtin "fcmp_ugt_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE32"(%909 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%121 = builtin "fcmp_ugt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%131 = builtin "fcmp_uge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%141 = builtin "fcmp_ult_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%151 = builtin "fcmp_ule_FPIEEE32"(%1 : $Builtin.FPIEEE32, %909 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL: sil @fold_float_comparison_with_inf
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %14 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %15 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %16 = tuple ()
|
|
// CHECK-NEXT: return %16 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_float_comparison_with_inf'
|
|
}
|
|
|
|
// fold double comparison operations involving literals only
|
|
sil @fold_literal_double_comparison : $@convention(thin) () -> () {
|
|
%0 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000 // 1
|
|
%1 = float_literal $Builtin.FPIEEE64, 0x4000000000000000 // 2
|
|
|
|
// Ordered
|
|
%3 = builtin "fcmp_oeq_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%4 = builtin "fcmp_ogt_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%8 = builtin "fcmp_one_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%9 = builtin "fcmp_ord_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%11 = builtin "fcmp_ueq_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%12 = builtin "fcmp_ugt_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%16 = builtin "fcmp_une_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%17 = builtin "fcmp_uno_FPIEEE64"(%0 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL:sil @fold_literal_double_comparison
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %14 = tuple ()
|
|
// CHECK-NEXT: return %14 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_literal_double_comparison'
|
|
}
|
|
|
|
// fold double comparison operations with NaN
|
|
sil @fold_double_comparison_with_nan : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000 // 1
|
|
%900 = integer_literal $Builtin.Int64, 9221120237041090560
|
|
%909 = builtin "bitcast_Int64_FPIEEE64"(%900 : $Builtin.Int64) : $Builtin.FPIEEE64
|
|
|
|
// Ordered
|
|
%3 = builtin "fcmp_oeq_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%4 = builtin "fcmp_ogt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%8 = builtin "fcmp_one_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%31 = builtin "fcmp_oeq_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%41 = builtin "fcmp_ogt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%51 = builtin "fcmp_oge_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%61 = builtin "fcmp_olt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%71 = builtin "fcmp_ole_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%81 = builtin "fcmp_one_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%11 = builtin "fcmp_ueq_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%12 = builtin "fcmp_ugt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%16 = builtin "fcmp_une_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%111 = builtin "fcmp_ueq_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%121 = builtin "fcmp_ugt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%131 = builtin "fcmp_uge_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%141 = builtin "fcmp_ult_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%151 = builtin "fcmp_ule_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%161 = builtin "fcmp_une_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL:sil @fold_double_comparison_with_nan
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %14 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %15 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %16 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %17 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %18 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %19 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %20 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %21 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %22 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %23 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %24 = tuple ()
|
|
// CHECK-NEXT: return %24 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_double_comparison_with_nan'
|
|
}
|
|
|
|
// fold double comparison operations with Infinity
|
|
sil @fold_double_comparison_with_inf : $@convention(thin) () -> () {
|
|
bb0:
|
|
%1 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000 // 1
|
|
%900 = integer_literal $Builtin.Int64, 9218868437227405312
|
|
%909 = builtin "bitcast_Int64_FPIEEE64"(%900 : $Builtin.Int64) : $Builtin.FPIEEE64
|
|
|
|
// Ordered
|
|
%4 = builtin "fcmp_ogt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%5 = builtin "fcmp_oge_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%6 = builtin "fcmp_olt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%7 = builtin "fcmp_ole_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%41 = builtin "fcmp_ogt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%51 = builtin "fcmp_oge_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%61 = builtin "fcmp_olt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%71 = builtin "fcmp_ole_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
// Unordered
|
|
%12 = builtin "fcmp_ugt_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%13 = builtin "fcmp_uge_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%15 = builtin "fcmp_ule_FPIEEE64"(%909 : $Builtin.FPIEEE64, %1 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%121 = builtin "fcmp_ugt_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%131 = builtin "fcmp_uge_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%141 = builtin "fcmp_ult_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
%151 = builtin "fcmp_ule_FPIEEE64"(%1 : $Builtin.FPIEEE64, %909 : $Builtin.FPIEEE64) : $Builtin.Int1
|
|
|
|
%404 = tuple ()
|
|
return %404 : $()
|
|
|
|
// CHECK-LABEL: sil @fold_double_comparison_with_inf
|
|
// CHECK-NEXT: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %1 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %2 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %4 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %5 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %6 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %7 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %8 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %9 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %10 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %11 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %12 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %13 = integer_literal $Builtin.Int1, 0
|
|
// CHECK-NEXT: %14 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %15 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: %16 = tuple ()
|
|
// CHECK-NEXT: return %16 : $()
|
|
// CHECK-NEXT: } // end sil function 'fold_double_comparison_with_inf'
|
|
}
|
|
|
|
sil @dont_fold_comparison_with_inf : $@convention(thin) (Builtin.FPIEEE32) -> Builtin.Int1 {
|
|
bb0(%0 : $Builtin.FPIEEE32):
|
|
%2 = float_literal $Builtin.FPIEEE32, 0x0
|
|
%4 = builtin "fadd_FPIEEE32"(%0 : $Builtin.FPIEEE32, %2 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32
|
|
%5 = integer_literal $Builtin.Int32, 2139095040
|
|
%6 = builtin "bitcast_Int32_FPIEEE32"(%5 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
%9 = builtin "fcmp_olt_FPIEEE32"(%4 : $Builtin.FPIEEE32, %6 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
return %9 : $Builtin.Int1
|
|
|
|
// CHECK-LABEL: sil @dont_fold_comparison_with_inf :
|
|
// CHECK: [[R:%.*]] = builtin "fcmp_olt_FPIEEE32"
|
|
// CHECK: return [[R]]
|
|
// CHECK: } // end sil function 'dont_fold_comparison_with_inf'
|
|
}
|
|
|
|
sil @fold_comparison_with_inf : $@convention(thin) () -> Builtin.Int1 {
|
|
bb0:
|
|
%2 = float_literal $Builtin.FPIEEE32, 0x7F800000 // +Inf // user: %3
|
|
%5 = integer_literal $Builtin.Int32, 2139095040
|
|
%6 = builtin "bitcast_Int32_FPIEEE32"(%5 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
%9 = builtin "fcmp_olt_FPIEEE32"(%2 : $Builtin.FPIEEE32, %6 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
return %9 : $Builtin.Int1
|
|
|
|
// CHECK-LABEL: sil @fold_comparison_with_inf :
|
|
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, 0
|
|
// CHECK: return [[R]]
|
|
// CHECK: } // end sil function 'fold_comparison_with_inf'
|
|
}
|
|
|
|
// fold float comparison operations with Infinity/NaN when the other argument is not constant
|
|
sil @fold_float_comparison_with_non_constant_arg : $@convention(thin) (Float) -> () {
|
|
bb0(%0: $Float):
|
|
%1 = struct_extract %0 : $Float, #Float._value
|
|
|
|
%2 = integer_literal $Builtin.Int32, 2143289344
|
|
%3 = builtin "bitcast_Int32_FPIEEE32"(%2 : $Builtin.Int32) : $Builtin.FPIEEE32 // NaN
|
|
|
|
%4 = integer_literal $Builtin.Int32, 2139095040
|
|
%5 = builtin "bitcast_Int32_FPIEEE32"(%4 : $Builtin.Int32) : $Builtin.FPIEEE32 // Inf
|
|
|
|
%6 = builtin "fcmp_oge_FPIEEE32"(%3 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%7 = builtin "fcmp_oge_FPIEEE32"(%5 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
|
|
// CHECK-LABEL: sil @fold_float_comparison_with_non_constant_arg
|
|
// CHECK: bb0(%0 : $Float):
|
|
// CHECK-NEXT: %1 = struct_extract %0 : $Float, #Float._value
|
|
// CHECK-NEXT: %2 = float_literal $Builtin.FPIEEE32, 0x7F800000 // +Inf
|
|
|
|
// Comparison with NaN is always folded
|
|
// CHECK-NEXT: %3 = integer_literal $Builtin.Int1, 0
|
|
|
|
// Comparison with Inf is not folded unless the other argument can be proven to be constant
|
|
// CHECK-NEXT: %4 = builtin "fcmp_oge_FPIEEE32"(%2 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
// CHECK-NEXT: %5 = tuple ()
|
|
// CHECK-NEXT: return %5
|
|
// CHECK-NEXT: } // end sil function 'fold_float_comparison_with_non_constant_arg'
|
|
}
|
|
|
|
sil @fold_inf_comparisons_with_itself : $@convention(thin) () -> () {
|
|
%0 = integer_literal $Builtin.Int32, 2139095040 // user: %4
|
|
%1 = builtin "bitcast_Int32_FPIEEE32"(%0 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
|
|
// Infinity is equal to, greater than equal to and less than equal to itself
|
|
%3 = builtin "fcmp_oeq_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%4 = builtin "fcmp_oge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%5 = builtin "fcmp_ole_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%6 = builtin "fcmp_ueq_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%7 = builtin "fcmp_uge_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%8 = builtin "fcmp_ule_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
// Infinity cannot be unequal to, greater than or less than itself
|
|
%9 = builtin "fcmp_one_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%10 = builtin "fcmp_ogt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%11 = builtin "fcmp_olt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%12 = builtin "fcmp_une_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%13 = builtin "fcmp_ugt_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
%14 = builtin "fcmp_ult_FPIEEE32"(%1 : $Builtin.FPIEEE32, %1 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
|
|
// CHECK-LABEL: sil @fold_inf_comparisons_with_itself
|
|
// CHECK: bb0:
|
|
// CHECK: %0 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %1 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %2 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %3 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %4 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %5 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %6 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %7 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %8 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %9 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %10 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %11 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: %12 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %13 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %14 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %15 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %16 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %17 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %18 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %19 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %20 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %21 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %22 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %23 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %24 = tuple ()
|
|
// CHECK: return %24 : $()
|
|
// CHECK: } // end sil function 'fold_inf_comparisons_with_itself'
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: sil @fold_cast_to_fp :
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: %0 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000 // 1
|
|
// CHECK-NEXT: return %0 : $Builtin.FPIEEE64
|
|
// CHECK: } // end sil function 'fold_cast_to_fp'
|
|
sil @fold_cast_to_fp : $@convention(thin) () -> Builtin.FPIEEE64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 1
|
|
%1 = builtin "sitofp_Int64_FPIEEE64"(%0) : $Builtin.FPIEEE64
|
|
return %1
|
|
}
|
|
|
|
// CHECK-LABEL: sil @fold_bitcast_to_fp :
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: %0 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
|
|
// CHECK-NEXT: return %0
|
|
// CHECK: } // end sil function 'fold_bitcast_to_fp'
|
|
sil @fold_bitcast_to_fp : $@convention(thin) () -> Builtin.FPIEEE64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 4607182418800017408
|
|
%1 = builtin "bitcast_Int64_FPIEEE64"(%0) : $Builtin.FPIEEE64
|
|
return %1
|
|
}
|
|
|
|
// CHECK-LABEL: sil @fold_bitcast_to_int :
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: %0 = integer_literal $Builtin.Int64, 4607182418800017408
|
|
// CHECK-NEXT: return %0
|
|
// CHECK: } // end sil function 'fold_bitcast_to_int'
|
|
sil @fold_bitcast_to_int : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = float_literal $Builtin.FPIEEE64, 0x3FF0000000000000
|
|
%1 = builtin "bitcast_FPIEEE64_Int64"(%0) : $Builtin.Int64
|
|
return %1
|
|
}
|
|
|
|
// CHECK-LABEL: sil @fold_rint :
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: %0 = float_literal $Builtin.FPIEEE64, 0x40F0000000000000 // 65536
|
|
// CHECK-NEXT: return %0 : $Builtin.FPIEEE64
|
|
// CHECK: } // end sil function 'fold_rint'
|
|
sil @fold_rint : $@convention(thin) () -> Builtin.FPIEEE64 {
|
|
bb0:
|
|
%0 = float_literal $Builtin.FPIEEE64, 0x40F0000000000000 // 65536
|
|
%1 = builtin "int_rint_FPIEEE64"(%0) : $Builtin.FPIEEE64
|
|
return %1
|
|
}
|
|
|
|
// fold float comparison operations with opaque values, that may be constant
|
|
// but are hidden behind a struct or a tuple.
|
|
sil @fold_float_comparison_between_opaque_val : $@convention(thin) () -> () {
|
|
%0 = integer_literal $Builtin.Int32, 2143289344
|
|
|
|
%1 = builtin "bitcast_Int32_FPIEEE32"(%0 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
%2 = struct $Float (%1 : $Builtin.FPIEEE32)
|
|
%3 = struct_extract %2 : $Float, #Float._value
|
|
%4 = integer_literal $Builtin.Int32, 2139095040
|
|
|
|
%5 = builtin "bitcast_Int32_FPIEEE32"(%4 : $Builtin.Int32) : $Builtin.FPIEEE32
|
|
%6 = struct $Float (%5 : $Builtin.FPIEEE32)
|
|
%7 = struct_extract %6 : $Float, #Float._value
|
|
|
|
%8 = builtin "fcmp_olt_FPIEEE32"(%3 : $Builtin.FPIEEE32, %7 : $Builtin.FPIEEE32) : $Builtin.Int1
|
|
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
|
|
// CHECK-LABEL: sil @fold_float_comparison_between_opaque_val
|
|
// CHECK: bb0:
|
|
// CHECK: %0 = integer_literal $Builtin.Int1, 0
|
|
// CHECK: %1 = tuple ()
|
|
// CHECK: return %1 : $()
|
|
// CHECK: } // end sil function 'fold_float_comparison_between_opaque_val'
|
|
}
|
|
|
|
// fold_float_arith_operations
|
|
sil @fold_float_arith_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_arith_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.IntLiteral, 1 // user: %2
|
|
%2 = builtin "s_to_s_checked_trunc_IntLiteral_Int64"(%0 : $Builtin.IntLiteral) : $(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.IntLiteral, 2 // user: %8
|
|
%8 = builtin "s_to_s_checked_trunc_IntLiteral_Int64"(%6 : $Builtin.IntLiteral) : $(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.IntLiteral, 1
|
|
%5 = builtin "s_to_u_checked_trunc_IntLiteral_Word"(%3 : $Builtin.IntLiteral) : $(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.IntLiteral, 0
|
|
%11 = builtin "s_to_u_checked_trunc_IntLiteral_Word"(%9 : $Builtin.IntLiteral) : $(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.IntLiteral, 1
|
|
%17 = builtin "s_to_u_checked_trunc_IntLiteral_Word"(%15 : $Builtin.IntLiteral) : $(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.IntLiteral, 0
|
|
%27 = builtin "s_to_s_checked_trunc_IntLiteral_Word"(%25 : $Builtin.IntLiteral) : $(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: [[ONE:%[0-9]+]] = integer_literal $Builtin.Int1, -1
|
|
// CHECK: cond_fail [[ONE]] : $Builtin.Int1, "failed cast"
|
|
// 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 AnObject in %31 : $*AnObject to Value in %2 : $*Value
|
|
%32 = alloc_stack $AnObject
|
|
dealloc_stack %32: $*AnObject
|
|
dealloc_stack %31 : $*AnObject
|
|
br bb1
|
|
}
|
|
|
|
public protocol P {
|
|
}
|
|
|
|
public protocol PP {
|
|
}
|
|
|
|
struct X : P {
|
|
}
|
|
|
|
struct Y<T>: P {
|
|
var x : T
|
|
}
|
|
|
|
class Z: P {
|
|
init()
|
|
}
|
|
|
|
// Do not optimize casts to unrelated protocols.
|
|
// CHECK-LABEL: sil @dont_replace_unconditional_check_cast_addr_for_type_to_unrelated_existential
|
|
// CHECK: unconditional_checked_cast_addr
|
|
// CHECK: end sil function 'dont_replace_unconditional_check_cast_addr_for_type_to_unrelated_existential'
|
|
sil @dont_replace_unconditional_check_cast_addr_for_type_to_unrelated_existential : $@convention(thin) (@in X) -> (@out PP) {
|
|
bb0(%0 : $*PP, %1 : $*X):
|
|
unconditional_checked_cast_addr X in %1 : $*X to PP in %0 : $*PP
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// Do not optimize casts between existentials.
|
|
// CHECK-LABEL: sil @dont_replace_unconditional_check_cast_addr_for_existential_to_existential
|
|
// CHECK: unconditional_checked_cast_addr
|
|
// CHECK: end sil function 'dont_replace_unconditional_check_cast_addr_for_existential_to_existential'
|
|
sil @dont_replace_unconditional_check_cast_addr_for_existential_to_existential : $@convention(thin) (@in PP) -> (@out P) {
|
|
bb0(%0 : $*P, %1 : $*PP):
|
|
unconditional_checked_cast_addr PP in %1 : $*PP to P in %0 : $*P
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// Check that an unconditional_checked_cast_addr from a non-existential loadable type to a protocol
|
|
// can be replaced by a more efficient code sequence if it is statistically known that this
|
|
// type conforms to this protocol.
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_type_to_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential
|
|
// CHECK-NOT: store
|
|
// CHECK: copy_addr
|
|
// CHECK-NOT: destroy_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
sil @replace_unconditional_check_cast_addr_for_type_to_existential : $@convention(thin) (@in X) -> (@out P) {
|
|
bb0(%0 : $*P, %1 : $*X):
|
|
unconditional_checked_cast_addr X in %1 : $*X to P in %0 : $*P
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_class_to_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
sil @replace_unconditional_check_cast_addr_for_class_to_existential : $@convention(thin) (@in Z) -> (@out P) {
|
|
bb0(%0 : $*P, %1 : $*Z):
|
|
unconditional_checked_cast_addr Z in %1 : $*Z to P in %0 : $*P
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_archetype_to_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
sil @replace_unconditional_check_cast_addr_for_archetype_to_existential : $@convention(thin) <X:P> (@in X) -> (@out P) {
|
|
bb0(%0 : $*P, %1 : $*X):
|
|
unconditional_checked_cast_addr X in %1 : $*X to P in %0 : $*P
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_generic_type_to_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
sil @replace_unconditional_check_cast_addr_for_generic_type_to_existential : $@convention(thin) <X:P> (@in Y<X>) -> (@out P) {
|
|
bb0(%0 : $*P, %1 : $*Y<X>):
|
|
unconditional_checked_cast_addr Y<X> in %1 : $*Y<X> to P in %0 : $*P
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
protocol Q : class {
|
|
}
|
|
|
|
class V : Q {
|
|
init()
|
|
}
|
|
|
|
class W<T>: Q {
|
|
var x : T
|
|
init()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_type_to_class_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK-NOT: retain_value
|
|
// CHECK: init_existential_ref
|
|
// CHECK-NOT: retain_value
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_for_type_to_class_existential : $@convention(thin) (@in V) -> (@out Q) {
|
|
bb0(%0 : $*Q, %1 : $*V):
|
|
unconditional_checked_cast_addr V in %1 : $*V to Q in %0 : $*Q
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_archetype_to_class_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK-NOT: retain_value
|
|
// CHECK: init_existential_ref
|
|
// CHECK-NOT: retain_value
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_for_archetype_to_class_existential : $@convention(thin) <X:Q> (@in X) -> (@out Q) {
|
|
bb0(%0 : $*Q, %1 : $*X):
|
|
unconditional_checked_cast_addr X in %1 : $*X to Q in %0 : $*Q
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_to_class_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK-NOT: retain_value
|
|
// CHECK: init_existential_ref
|
|
// CHECK-NOT: retain_value
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_to_class_existential : $@convention(thin) <X:Q> (@in W<X>) -> (@out Q) {
|
|
bb0(%0 : $*Q, %1 : $*W<X>):
|
|
unconditional_checked_cast_addr W<X> in %1 : $*W<X> to Q in %0 : $*Q
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
public protocol MyError : Error {
|
|
}
|
|
|
|
public class E1 : MyError {
|
|
init()
|
|
}
|
|
|
|
public class E2<T> : MyError {
|
|
init()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_type_to_myerror_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_for_type_to_myerror_existential : $@convention(thin) (@in E1) -> (@out MyError) {
|
|
bb0(%0 : $*MyError, %1 : $*E1):
|
|
unconditional_checked_cast_addr E1 in %1 : $*E1 to MyError in %0 : $*MyError
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_archetype_to_myerror_existentia
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_for_archetype_to_myerror_existential : $@convention(thin) <X:MyError> (@in X) -> (@out MyError) {
|
|
bb0(%0 : $*MyError, %1 : $*X):
|
|
unconditional_checked_cast_addr X in %1 : $*X to MyError in %0 : $*MyError
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_to_myerror_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: init_existential_addr
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_to_myerror_existential : $@convention(thin) <X:MyError> (@in E2<X>) -> (@out MyError) {
|
|
bb0(%0 : $*MyError, %1 : $*E2<X>):
|
|
unconditional_checked_cast_addr E2<X> in %1 : $*E2<X> to MyError in %0 : $*MyError
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// Check casts to Error.
|
|
// CHECK-LABEL: sil @replace_unconditional_check_cast_addr_for_type_to_error_existential
|
|
// CHECK-NOT: unconditional_checked_cast_addr
|
|
// CHECK: [[ALLOC_BOX:%.*]] = alloc_existential_box $any Error, $E1
|
|
// CHECK: [[PROJ:%.*]] = project_existential_box $E1 in [[ALLOC_BOX]] : $any Error
|
|
// CHECK: copy_addr [take] %1 to [init] [[PROJ]]
|
|
// CHECK: store [[ALLOC_BOX]] to %0 : $*any Error
|
|
// CHECK: return
|
|
sil @replace_unconditional_check_cast_addr_for_type_to_error_existential : $@convention(thin) (@in E1) -> (@out Error) {
|
|
bb0(%0 : $*Error, %1 : $*E1):
|
|
unconditional_checked_cast_addr E1 in %1 : $*E1 to Error in %0 : $*Error
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @generic_to_existential_cast
|
|
// CHECK: init_existential_addr
|
|
// CHECK: } // end sil function 'generic_to_existential_cast'
|
|
sil [ossa] @generic_to_existential_cast : $@convention(thin) <T where T : P> (@in_guaranteed T) -> @out any P {
|
|
bb0(%0: $*any P, %1 : $*T):
|
|
%29 = alloc_stack $T
|
|
copy_addr %1 to [init] %29
|
|
unconditional_checked_cast_addr T in %29 to any P in %0
|
|
dealloc_stack %29
|
|
%10 = tuple ()
|
|
return %10
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @existential_generic_to_existential_cast
|
|
// CHECK: unconditional_checked_cast_addr
|
|
// CHECK: } // end sil function 'existential_generic_to_existential_cast'
|
|
sil [ossa] @existential_generic_to_existential_cast : $@convention(thin) <T where T : Error> (@in_guaranteed T) -> @owned any Error {
|
|
bb0(%0 : $*T):
|
|
%29 = alloc_stack $T
|
|
copy_addr %0 to [init] %29
|
|
%31 = alloc_stack $any Error
|
|
unconditional_checked_cast_addr T in %29 to any Error in %31
|
|
%33 = load [take] %31
|
|
dealloc_stack %31
|
|
dealloc_stack %29
|
|
return %33
|
|
}
|
|
// Test constant folding of Builtin.globalStringTablePointer.
|
|
|
|
// CHECK-LABEL: sil @replace_global_string_table_pointer
|
|
// CHECK: [[STRING_LIT:%.*]] = string_literal utf8 "constant"
|
|
// CHECK-NOT: builtin "globalStringTablePointer"
|
|
// CHECK: [[IMMORTAL_PTR:%.*]] = struct $UnsafePointer<Int8> ([[STRING_LIT]] : $Builtin.RawPointer)
|
|
// CHECK: return [[IMMORTAL_PTR]]
|
|
sil @replace_global_string_table_pointer : $@convention(thin) () -> UnsafePointer<Int8> {
|
|
bb0:
|
|
%0 = string_literal utf8 "constant"
|
|
%1 = integer_literal $Builtin.Word, 8
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%4 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%5 = apply %4(%0, %1, %2, %3) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = builtin "globalStringTablePointer"(%5 : $String) : $Builtin.RawPointer
|
|
%7 = struct $UnsafePointer<Int8> (%6 : $Builtin.RawPointer)
|
|
release_value %5 : $String
|
|
return %7 : $UnsafePointer<Int8>
|
|
}
|
|
|
|
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
// The semantics attribute is used by the constant folder.
|
|
sil [serialized] [always_inline] [readonly] [_semantics "string.makeUTF8"] @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
|
|
// CHECK-LABEL: sil @string_ptr_to_int_round_trip : $@convention(thin) () -> Builtin.RawPointer {
|
|
// CHECK-NOT: builtin
|
|
// CHECK: } // end sil function 'string_ptr_to_int_round_trip'
|
|
sil @string_ptr_to_int_round_trip : $@convention(thin) () -> Builtin.RawPointer {
|
|
bb0:
|
|
%0 = string_literal utf8 "constant"
|
|
%1 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
|
|
%2 = builtin "inttoptr_Word"(%1 : $Builtin.Word) : $Builtin.RawPointer
|
|
return %2 : $Builtin.RawPointer
|
|
}
|
|
|
|
// CHECK-LABEL: sil @string_ptr_to_int_round_trip_2 : $@convention(thin) () -> Builtin.Word {
|
|
// CHECK-NOT: builtin
|
|
// CHECK: } // end sil function 'string_ptr_to_int_round_trip_2'
|
|
sil @string_ptr_to_int_round_trip_2 : $@convention(thin) () -> Builtin.Word {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Word, 0
|
|
%1 = builtin "inttoptr_Word"(%0 : $Builtin.Word) : $Builtin.RawPointer
|
|
%2 = builtin "ptrtoint_Word"(%1 : $Builtin.RawPointer) : $Builtin.Word
|
|
return %2 : $Builtin.Word
|
|
}
|
|
|
|
// CHECK-LABEL: sil @string_ptr_to_int_round_trip_no_match : $@convention(thin) () -> Builtin.Int32 {
|
|
// CHECK: builtin
|
|
// CHECK: builtin
|
|
// CHECK: } // end sil function 'string_ptr_to_int_round_trip_no_match'
|
|
sil @string_ptr_to_int_round_trip_no_match : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Word, 0
|
|
%1 = builtin "inttoptr_Word"(%0 : $Builtin.Word) : $Builtin.RawPointer
|
|
%2 = builtin "ptrtoint_Int32"(%1 : $Builtin.RawPointer) : $Builtin.Int32
|
|
return %2 : $Builtin.Int32
|
|
}
|
|
|
|
// Make sure that we perform the transformation, but do not eliminate the int1,
|
|
// since we do not know what it is.
|
|
//
|
|
// CHECK-LABEL: sil @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () {
|
|
// CHECK-NOT: builtin
|
|
// CHECK: cond_fail
|
|
// CHECK-NOT: builtin
|
|
// CHECK: } // end sil function 'cond_fail_test'
|
|
sil @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
%1 = string_literal utf8 "constant"
|
|
%2 = builtin "condfail_message"(%0 : $Builtin.Int1, %1 : $Builtin.RawPointer) : $()
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @simplify_struct_test : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
// CHECK-NOT: struct
|
|
// CHECK: } // end sil function 'simplify_struct_test'
|
|
sil @simplify_struct_test : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64):
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = struct_extract %1 : $Int64, #Int64.value
|
|
return %2 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: sil @simplify_tuple_test : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
// CHECK-NOT: tuple
|
|
// CHECK: } // end sil function 'simplify_tuple_test'
|
|
sil @simplify_tuple_test : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64):
|
|
%1 = tuple(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
|
|
%2 = tuple_extract %1 : $(Builtin.Int64, Builtin.Int64), 0
|
|
return %2 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: sil [canonical] @isConcrete_true : $@convention(thin) (@thin UInt.Type) -> Builtin.Int1 {
|
|
// CHECK: bb0(
|
|
// CHECK-NEXT: [[RESULT:%.*]] = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
// CHECK-NEXT: } // end sil function 'isConcrete_true'
|
|
sil [canonical] @isConcrete_true : $@convention(thin) (@thin UInt.Type) -> Builtin.Int1 {
|
|
bb0(%0 : $@thin UInt.Type):
|
|
%1 = builtin "isConcrete"(%0 : $@thin UInt.Type) : $Builtin.Int1
|
|
return %1 : $Builtin.Int1
|
|
}
|
|
|
|
// CHECK-LABEL: sil [canonical] @isConcrete_false : $@convention(thin) <T> (@thin T.Type) -> Builtin.Int1 {
|
|
// CHECK: bb0(
|
|
// CHECK-NEXT: [[RESULT:%.*]] = builtin "isConcrete"(
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
// CHECK-NEXT: } // end sil function 'isConcrete_false'
|
|
sil [canonical] @isConcrete_false : $@convention(thin) <T> (@thin T.Type) -> Builtin.Int1 {
|
|
bb0(%0 : $@thin T.Type):
|
|
%1 = builtin "isConcrete"(%0 : $@thin T.Type) : $Builtin.Int1
|
|
return %1 : $Builtin.Int1
|
|
}
|
|
|
|
class AClass {}
|
|
class BClass : AClass {}
|
|
|
|
// CHECK-LABEL: sil @test_checked_cast_br_thick_class_type
|
|
// CHECK: [[METATYPE:%.*]] = metatype $@thick BClass.Type
|
|
// CHECK: [[SUPER:%.*]] = upcast [[METATYPE]] : $@thick BClass.Type to $@thick AClass.Type
|
|
// CHECK: br bb1([[SUPER]] : $@thick AClass.Type)
|
|
sil @test_checked_cast_br_thick_class_type : $@convention(thin) (@thin P.Protocol) -> Builtin.Int1 {
|
|
bb0(%0 : $@thin P.Protocol):
|
|
%2 = metatype $@thick BClass.Type
|
|
checked_cast_br BClass.Type in %2 : $@thick BClass.Type to AClass.Type, bb1, bb2
|
|
|
|
bb1(%5 : $@thick AClass.Type):
|
|
debug_value %5 : $@thick AClass.Type, let, name "type"
|
|
%6 = integer_literal $Builtin.Int1, -1
|
|
br bb3(%6 : $Builtin.Int1)
|
|
|
|
bb2:
|
|
%9 = integer_literal $Builtin.Int1, 0
|
|
br bb3(%9 : $Builtin.Int1)
|
|
|
|
bb3(%11 : $Builtin.Int1):
|
|
return %11 : $Builtin.Int1
|
|
}
|