mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
It is necessary for opaque values where for casts that will newly start out as checked_cast_brs and be lowered to checked_cast_addr_brs, since the latter has the source formal type, IRGen relies on being able to access it, and there's no way in general to obtain the source formal type from the source lowered type.
1557 lines
65 KiB
Plaintext
1557 lines
65 KiB
Plaintext
// RUN: %target-sil-opt -test-constant-evaluator %s 2>&1 | %FileCheck %s
|
|
|
|
/// Tests for the constant evaluator in stepwise evaluation mode (also referred
|
|
/// to as flow-sensitive mode) in which instructions are evaluated following
|
|
/// the control flow of the program. The evaluator will be run on every function
|
|
/// whose name starts with `interpret` prefix and outputs the constant value
|
|
/// returned by the function or diagnostics if the evaluation fails.
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
// Test builtin literals and operations.
|
|
|
|
// CHECK-LABEL: @interpretBuiltinIntLiteral
|
|
sil @interpretBuiltinIntLiteral : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 17
|
|
return %0 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: 17
|
|
|
|
// CHECK-LABEL: @interpretBuiltinAddition
|
|
sil @interpretBuiltinAddition : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 1
|
|
%1 = builtin "add_Int32"(%0 : $Builtin.Int32, %0 : $Builtin.Int32) : $(Builtin.Int32)
|
|
return %1 : $(Builtin.Int32)
|
|
} // CHECK: Returns int: 2
|
|
|
|
// CHECK-LABEL: @interpretBuiltinAddWrapAround
|
|
sil @interpretBuiltinAddWrapAround : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 127
|
|
%1 = integer_literal $Builtin.Int8, 1
|
|
%2 = builtin "add_Int32"(%0 : $Builtin.Int8, %1 : $Builtin.Int8) : $(Builtin.Int8)
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: -128
|
|
|
|
// CHECK-LABEL: @interpretBuiltinMultiplication
|
|
sil @interpretBuiltinMultiplication : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 10
|
|
%1 = integer_literal $Builtin.Int64, 11
|
|
%2 = builtin "mul_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64) : $(Builtin.Int64)
|
|
return %2 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: 110
|
|
|
|
// CHECK-LABEL: @interpretBuiltinDivision
|
|
sil @interpretBuiltinDivision : $@convention(thin) () -> Builtin.Int16 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int16, 10
|
|
%1 = integer_literal $Builtin.Int16, 11
|
|
%2 = builtin "sdiv_Int16"(%1 : $Builtin.Int16, %0 : $Builtin.Int16) : $(Builtin.Int16)
|
|
return %2 : $(Builtin.Int16)
|
|
} // CHECK: Returns int: 1
|
|
|
|
// CHECK-LABEL: @interpretBuiltinModulo
|
|
sil @interpretBuiltinModulo : $@convention(thin) () -> Builtin.Int16 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int16, 23
|
|
%1 = integer_literal $Builtin.Int16, 6
|
|
%2 = builtin "srem_Int16"(%0 : $Builtin.Int16, %1 : $Builtin.Int16) : $(Builtin.Int16)
|
|
return %2 : $(Builtin.Int16)
|
|
} // CHECK: Returns int: 5
|
|
|
|
// CHECK-LABEL: @interpretBuiltinLeftShift
|
|
sil @interpretBuiltinLeftShift : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 10
|
|
%1 = integer_literal $Builtin.Int8, 2
|
|
%2 = builtin "shl_Int8"(%0 : $Builtin.Int8, %1: $Builtin.Int8) : $(Builtin.Int8)
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: 40
|
|
|
|
// CHECK-LABEL: @interpretBuiltinRightShift
|
|
sil @interpretBuiltinRightShift : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 10
|
|
%1 = integer_literal $Builtin.Int8, 2
|
|
%2 = builtin "ashr_Int8"(%0 : $Builtin.Int8, %1: $Builtin.Int8) : $(Builtin.Int8)
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: 2
|
|
|
|
// CHECK-LABEL: @interpretBuiltinBitWiseAnd
|
|
sil @interpretBuiltinBitWiseAnd : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 10
|
|
%1 = integer_literal $Builtin.Int8, 8
|
|
%2 = builtin "and_Int8"(%0 : $Builtin.Int8, %1: $Builtin.Int8) : $(Builtin.Int8)
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: 8
|
|
|
|
// CHECK-LABEL: @interpretBuiltinBitWiseOr
|
|
sil @interpretBuiltinBitWiseOr : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 10
|
|
%1 = integer_literal $Builtin.Int8, 8
|
|
%2 = builtin "or_Int8"(%0 : $Builtin.Int8, %1: $Builtin.Int8) : $(Builtin.Int8)
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: 10
|
|
|
|
// Test conditional branches and comparison operators.
|
|
|
|
// CHECK-LABEL: @interpretFalseBranch
|
|
sil hidden @interpretFalseBranch : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = integer_literal $Builtin.Int64, 100
|
|
%2 = integer_literal $Builtin.Int64, 0
|
|
%3 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int1
|
|
cond_br %3, bb1, bb2
|
|
|
|
bb1:
|
|
%8 = integer_literal $Builtin.Int64, 0
|
|
br bb3(%8 : $Builtin.Int64)
|
|
|
|
bb2:
|
|
br bb3(%1 : $Builtin.Int64)
|
|
|
|
bb3(%12 : $Builtin.Int64):
|
|
return %12 : $Builtin.Int64
|
|
} // CHECK: Returns int: 100
|
|
|
|
// CHECK-LABEL: @interpretTrueBranch
|
|
sil hidden @interpretTrueBranch : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = integer_literal $Builtin.Int64, 100
|
|
%2 = integer_literal $Builtin.Int64, 0
|
|
%3 = builtin "cmp_slt_Int64"(%1 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int1
|
|
%4 = integer_literal $Builtin.Int1, -1
|
|
%5 = builtin "xor_Int1"(%3 : $Builtin.Int1, %4 : $Builtin.Int1) : $Builtin.Int1
|
|
cond_br %5, bb1, bb2
|
|
|
|
bb1:
|
|
%8 = integer_literal $Builtin.Int64, 0
|
|
br bb3(%8 : $Builtin.Int64)
|
|
|
|
bb2:
|
|
br bb3(%1 : $Builtin.Int64)
|
|
|
|
bb3(%12 : $Builtin.Int64):
|
|
return %12 : $Builtin.Int64
|
|
} // CHECK: Returns int: 0
|
|
|
|
// Test builtin truncation and extension.
|
|
|
|
// CHECK-LABEL: @interpretSignedTruncation
|
|
sil @interpretSignedTruncation : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, -1
|
|
%1 = builtin "s_to_s_checked_trunc_Int64_Int8"(%0 : $Builtin.Int64) : $(Builtin.Int8, Builtin.Int1)
|
|
%2 = tuple_extract %1 : $(Builtin.Int8, Builtin.Int1), 0
|
|
return %2 : $(Builtin.Int8)
|
|
} // CHECK: Returns int: -1
|
|
|
|
// CHECK-LABEL: @interpretSignedTruncWithIntLiteral
|
|
sil @interpretSignedTruncWithIntLiteral : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.IntLiteral, 5
|
|
%1 = builtin "s_to_s_checked_trunc_IntLiteral_Int64"(%0 : $Builtin.IntLiteral) : $(Builtin.Int64, Builtin.Int1)
|
|
%2 = tuple_extract %1 : $(Builtin.Int64, Builtin.Int1), 0
|
|
return %2 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: 5
|
|
|
|
// CHECK-LABEL: @interpretSignedExtend
|
|
sil @interpretSignedExtend : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, -1
|
|
%1 = builtin "sext_Int8_Int64"(%0 : $Builtin.Int8) : $Builtin.Int64
|
|
return %1 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: -1
|
|
|
|
// CHECK-LABEL: @interpretZeroExtend
|
|
sil @interpretZeroExtend : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, -1
|
|
%1 = builtin "zext_Int8_Int64"(%0 : $Builtin.Int8) : $Builtin.Int64
|
|
return %1 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: 255
|
|
|
|
// FIXME: assertion failure in conversion of s_to_s_checked_trunc_IntLiteral.
|
|
sil @xfailInterpretBuiltinIntLiteralTrunc : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.IntLiteral, 2
|
|
%2 = builtin "s_to_s_checked_trunc_IntLiteral_Int8"(%0 : $Builtin.IntLiteral) : $(Builtin.Int8, Builtin.Int1)
|
|
%3 = tuple_extract %2 : $(Builtin.Int8, Builtin.Int1), 0
|
|
return %3 : $(Builtin.Int8)
|
|
}
|
|
|
|
// Test overflow diagnostics.
|
|
// FIXME: Imprecision: the following builtin operations return a tuple where
|
|
// the second element indicate whether an overflow happened or not.
|
|
// The interpreter currently makes the entire tuple unknown in the case of
|
|
// overflow. This should be replaced by the correct semantics of the builtin
|
|
// which produces a truncated value for the first element and returns true for
|
|
// the second element.
|
|
|
|
// CHECK-LABEL: @interpretSignedTruncationError
|
|
sil @interpretSignedTruncationError : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, -1
|
|
%1 = builtin "s_to_u_checked_trunc_Int64_Int8"(%0 : $Builtin.Int64) : $(Builtin.Int8, Builtin.Int1)
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: integer overflow detected
|
|
%2 = tuple_extract %1 : $(Builtin.Int8, Builtin.Int1), 0
|
|
return %2 : $(Builtin.Int8)
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretBuiltinAddOverflow
|
|
sil @interpretBuiltinAddOverflow : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int8, 127
|
|
%1 = integer_literal $Builtin.Int8, 1
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = builtin "sadd_with_overflow_Int8"(%0 : $Builtin.Int8, %1 : $Builtin.Int8, %2: $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1)
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: integer overflow detected
|
|
%4 = tuple_extract %3 : $(Builtin.Int8, Builtin.Int1), 0
|
|
return %4 : $(Builtin.Int8)
|
|
}
|
|
|
|
// Test function calls
|
|
|
|
sil hidden @identity : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64):
|
|
return %0 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretCallTest
|
|
sil hidden @interpretCallTest : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 10
|
|
%2 = function_ref @identity : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
%3 = apply %2(%0) : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
return %3 : $Builtin.Int64
|
|
} // CHECK: Returns int: 10
|
|
|
|
// A function that computes factorial of a Builtin.Int64 and traps on overflow.
|
|
sil hidden @factorial : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 {
|
|
bb0(%0 : $Builtin.Int64):
|
|
%2 = integer_literal $Builtin.Int64, 0
|
|
%4 = builtin "cmp_eq_Int64"(%0 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int1
|
|
cond_br %4, bb1, bb2
|
|
|
|
bb1:
|
|
%8 = integer_literal $Builtin.Int64, 1
|
|
br bb3(%8 : $Builtin.Int64)
|
|
|
|
bb2:
|
|
%11 = integer_literal $Builtin.Int64, 1
|
|
%13 = integer_literal $Builtin.Int1, -1
|
|
%14 = builtin "usub_with_overflow_Int64"(%0 : $Builtin.Int64, %11 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%16 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %16 : $Builtin.Int1
|
|
%19 = function_ref @factorial : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
%20 = apply %19(%15) : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
%23 = integer_literal $Builtin.Int1, -1
|
|
%24 = builtin "umul_with_overflow_Int64"(%0 : $Builtin.Int64, %20 : $Builtin.Int64, %23 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%25 = tuple_extract %24 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%26 = tuple_extract %24 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %26 : $Builtin.Int1
|
|
br bb3(%25 : $Builtin.Int64)
|
|
|
|
bb3(%30 : $Builtin.Int64):
|
|
return %30 : $Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretFactorialCall
|
|
sil hidden @interpretFactorialCall : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 5
|
|
%2 = function_ref @factorial : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
%3 = apply %2(%0) : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
return %3 : $Builtin.Int64
|
|
} // CHECK: Returns int: 120
|
|
|
|
// CHECK-LABEL: @interpretAndDiagnoseLongRecursion
|
|
sil hidden @interpretAndDiagnoseLongRecursion : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, -5
|
|
%2 = function_ref @factorial : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
%3 = apply %2(%0) : $@convention(thin) (Builtin.Int64) -> Builtin.Int64
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: exceeded instruction limit: {{.*}} when evaluating the expression at compile time
|
|
// CHECK: {{.*}}: note: limit exceeded here
|
|
return %3 : $Builtin.Int64
|
|
}
|
|
|
|
// Test meta types.
|
|
|
|
// CHECK-LABEL: @interpretIntMetatype
|
|
sil @interpretIntMetatype : $@convention(thin) () -> @thin Int.Type {
|
|
bb0:
|
|
%0 = metatype $@thin Int.Type
|
|
return %0 : $@thin Int.Type
|
|
} // CHECK: Returns metatype: Int
|
|
|
|
// CHECK-LABEL: @interpretStringMetatype
|
|
sil @interpretStringMetatype : $@convention(thin) () -> @thin String.Type {
|
|
bb0:
|
|
%0 = metatype $@thin String.Type
|
|
return %0 : $@thin String.Type
|
|
} // CHECK: Returns metatype: String
|
|
|
|
// Test standard integers.
|
|
|
|
// CHECK-LABEL: @interpretIntInit
|
|
sil @interpretIntInit : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 122
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = struct_extract %1 : $Int64, #Int64._value
|
|
return %2 : $Builtin.Int64
|
|
} // CHECK: Returns int: 122
|
|
|
|
sil @mockInt8Init : $@convention(thin) (Builtin.Int64, @thin Int8.Type) -> Int8 {
|
|
bb0(%0 : $Builtin.Int64, %1 : $@thin Int8.Type):
|
|
%2 = builtin "s_to_s_checked_trunc_Int64_Int8"(%0 : $Builtin.Int64) : $(Builtin.Int8, Builtin.Int1)
|
|
%3 = tuple_extract %2 : $(Builtin.Int8, Builtin.Int1), 0
|
|
%4 = struct $Int8 (%3 : $Builtin.Int8)
|
|
return %4 : $Int8
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretInt8Init
|
|
sil @interpretInt8Init : $@convention(thin) () -> Builtin.Int8 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 122
|
|
%1 = metatype $@thin Int8.Type
|
|
%2 = function_ref @mockInt8Init : $@convention(thin) (Builtin.Int64, @thin Int8.Type) -> Int8
|
|
%3 = apply %2(%0, %1) : $@convention(thin) (Builtin.Int64, @thin Int8.Type) -> Int8
|
|
%4 = struct_extract %3 : $Int8, #Int8._value
|
|
return %4 : $Builtin.Int8
|
|
} // CHECK: Returns int: 122
|
|
|
|
sil @boolEquals : $@convention(method) (Bool, Bool, @thin Bool.Type) -> Bool {
|
|
bb0(%0 : $Bool, %1 : $Bool, %2 : $@thin Bool.Type):
|
|
%3 = struct_extract %0 : $Bool, #Bool._value
|
|
%4 = struct_extract %1 : $Bool, #Bool._value
|
|
%5 = builtin "cmp_eq_Int1"(%3 : $Builtin.Int1, %4 : $Builtin.Int1) : $Builtin.Int1
|
|
%6 = struct $Bool (%5 : $Builtin.Int1)
|
|
return %6 : $Bool
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretBoolEquals
|
|
sil @interpretBoolEquals : $@convention(thin) () -> Builtin.Int1 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int1, 0
|
|
%1 = struct $Bool (%0 : $Builtin.Int1)
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = struct $Bool (%2 : $Builtin.Int1)
|
|
%4 = metatype $@thin Bool.Type
|
|
%5 = function_ref @boolEquals : $@convention(method) (Bool, Bool, @thin Bool.Type) -> Bool
|
|
%6 = apply %5(%1, %3, %4) : $@convention(method) (Bool, Bool, @thin Bool.Type) -> Bool
|
|
%7 = struct_extract %6 : $Bool, #Bool._value
|
|
return %7 : $Builtin.Int1
|
|
} // CHECK: Returns int: 0
|
|
|
|
// Test custom structs.
|
|
|
|
struct InnerStruct {
|
|
var z: Int64
|
|
var w: Bool
|
|
}
|
|
|
|
struct CustomStruct {
|
|
let x: (Int64, Int64)
|
|
let y: InnerStruct
|
|
}
|
|
|
|
sil @innerStructInit : $@convention(method) (Int64, Bool, @thin InnerStruct.Type) -> InnerStruct {
|
|
bb0(%0 : $Int64, %1 : $Bool, %2 : $@thin InnerStruct.Type):
|
|
%3 = struct $InnerStruct (%0 : $Int64, %1 : $Bool)
|
|
return %3 : $InnerStruct
|
|
}
|
|
|
|
sil @customStructInit : $@convention(method) (Int64, Int64, InnerStruct, @thin CustomStruct.Type) -> CustomStruct {
|
|
bb0(%0 : $Int64, %1 : $Int64, %2 : $InnerStruct, %3 : $@thin CustomStruct.Type):
|
|
%4 = tuple (%0 : $Int64, %1 : $Int64)
|
|
%5 = struct $CustomStruct (%4 : $(Int64, Int64), %2 : $InnerStruct)
|
|
return %5 : $CustomStruct
|
|
}
|
|
|
|
sil @constructCustomStruct : $@convention(thin) () -> CustomStruct {
|
|
bb0:
|
|
%0 = metatype $@thin CustomStruct.Type
|
|
%1 = integer_literal $Builtin.Int64, 1
|
|
%2 = struct $Int64 (%1 : $Builtin.Int64)
|
|
%3 = integer_literal $Builtin.Int64, 2
|
|
%4 = struct $Int64 (%3 : $Builtin.Int64)
|
|
%5 = metatype $@thin InnerStruct.Type
|
|
%6 = integer_literal $Builtin.Int64, 3
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, -1
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
|
|
%10 = function_ref @innerStructInit : $@convention(method) (Int64, Bool, @thin InnerStruct.Type) -> InnerStruct
|
|
%11 = apply %10(%7, %9, %5) : $@convention(method) (Int64, Bool, @thin InnerStruct.Type) -> InnerStruct
|
|
|
|
%12 = function_ref @customStructInit : $@convention(method) (Int64, Int64, InnerStruct, @thin CustomStruct.Type) -> CustomStruct
|
|
%13 = apply %12(%2, %4, %11, %0) : $@convention(method) (Int64, Int64, InnerStruct, @thin CustomStruct.Type) -> CustomStruct
|
|
return %13 : $CustomStruct
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretCustomStruct
|
|
sil @interpretCustomStruct : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = function_ref @constructCustomStruct : $@convention(thin) () -> CustomStruct
|
|
%2 = apply %1() : $@convention(thin) () -> CustomStruct
|
|
%3 = struct_extract %2 : $CustomStruct, #CustomStruct.x
|
|
%4 = tuple_extract %3 : $(Int64, Int64), 0
|
|
%5 = struct_extract %4 : $Int64, #Int64._value
|
|
return %5 : $Builtin.Int64
|
|
} // CHECK: Returns int: 1
|
|
|
|
// CHECK-LABEL: @interpretCustomStruct2
|
|
sil @interpretCustomStruct2 : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = function_ref @constructCustomStruct : $@convention(thin) () -> CustomStruct
|
|
%2 = apply %1() : $@convention(thin) () -> CustomStruct
|
|
%3 = struct_extract %2 : $CustomStruct, #CustomStruct.x
|
|
%4 = tuple_extract %3 : $(Int64, Int64), 1
|
|
%5 = struct_extract %4 : $Int64, #Int64._value
|
|
return %5 : $Builtin.Int64
|
|
} // CHECK: Returns int: 2
|
|
|
|
// CHECK-LABEL: @interpretCustomStruct3
|
|
sil @interpretCustomStruct3 : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = function_ref @constructCustomStruct : $@convention(thin) () -> CustomStruct
|
|
%2 = apply %1() : $@convention(thin) () -> CustomStruct
|
|
%3 = struct_extract %2 : $CustomStruct, #CustomStruct.y
|
|
%4 = struct_extract %3 : $InnerStruct, #InnerStruct.z
|
|
%5 = struct_extract %4 : $Int64, #Int64._value
|
|
return %5 : $Builtin.Int64
|
|
} // CHECK: Returns int: 3
|
|
|
|
// CHECK-LABEL: @interpretCustomStruct4
|
|
sil @interpretCustomStruct4 : $@convention(thin) () -> Builtin.Int1 {
|
|
bb0:
|
|
%1 = function_ref @constructCustomStruct : $@convention(thin) () -> CustomStruct
|
|
%2 = apply %1() : $@convention(thin) () -> CustomStruct
|
|
%3 = struct_extract %2 : $CustomStruct, #CustomStruct.y
|
|
%4 = struct_extract %3 : $InnerStruct, #InnerStruct.w
|
|
%5 = struct_extract %4 : $Bool, #Bool._value
|
|
return %5 : $Builtin.Int1
|
|
} // CHECK: Returns int: -1
|
|
|
|
// Test non-constant diagnostics.
|
|
|
|
// CHECK-LABEL: @interpretAndDiagnoseNonConstantVars
|
|
sil hidden @interpretAndDiagnoseNonConstantVars : $@convention(thin) (Int) -> () {
|
|
bb0(%0 : $Int):
|
|
%4 = struct_extract %0 : $Int, #Int._value
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: encountered use of a variable not tracked by the evaluator
|
|
%10 = tuple ()
|
|
return %10 : $()
|
|
}
|
|
|
|
sil @$ss8readLine16strippingNewlineSSSgSb_tF : $@convention(thin) (Bool) -> @owned Optional<String>
|
|
|
|
// CHECK-LABEL: @interpretAndDiagnoseNonConstantCalls
|
|
sil @interpretAndDiagnoseNonConstantCalls : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int1, -1
|
|
%1 = struct $Bool (%0 : $Builtin.Int1)
|
|
// function_ref readLine(strippingNewline:)
|
|
%2 = function_ref @$ss8readLine16strippingNewlineSSSgSb_tF : $@convention(thin) (Bool) -> @owned Optional<String>
|
|
%3 = apply %2(%1) : $@convention(thin) (Bool) -> @owned Optional<String>
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: encountered call to 'readLine(strippingNewline:)' whose body is not available
|
|
release_value %3 : $Optional<String>
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// Test loop diagnostics.
|
|
|
|
// CHECK-LABEL: @interpretAndDiagnoseLoops
|
|
sil hidden @interpretAndDiagnoseLoops : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = integer_literal $Builtin.Int64, 0
|
|
%4 = integer_literal $Builtin.Int64, 100
|
|
|
|
%5 = builtin "cmp_slt_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) : $Builtin.Int1
|
|
cond_br %5, bb2, bb3
|
|
|
|
bb2:
|
|
br bb1
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: control-flow loop found during evaluation
|
|
|
|
bb3:
|
|
%10 = tuple ()
|
|
return %10 : $()
|
|
}
|
|
|
|
// Test stack allocation and memory access.
|
|
|
|
// CHECK-LABEL: @interpretLoadStore
|
|
sil hidden @interpretLoadStore : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = alloc_stack $Builtin.Int64, var, name "i"
|
|
%1 = integer_literal $Builtin.Int64, 11
|
|
store %1 to %0 : $*Builtin.Int64
|
|
%3 = load %0 : $*Builtin.Int64
|
|
dealloc_stack %0 : $*Builtin.Int64
|
|
return %3 : $Builtin.Int64
|
|
} // CHECK: Returns int: 11
|
|
|
|
// CHECK-LABEL: @interpretBeginEndAccess
|
|
sil hidden @interpretBeginEndAccess : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = alloc_stack $Builtin.Int64, var, name "i"
|
|
%1 = integer_literal $Builtin.Int64, 11
|
|
%3 = begin_access [modify] [static] %0 : $*Builtin.Int64
|
|
store %1 to %3 : $*Builtin.Int64
|
|
end_access %3 : $*Builtin.Int64
|
|
%5 = load %0 : $*Builtin.Int64
|
|
dealloc_stack %0 : $*Builtin.Int64
|
|
return %5 : $Builtin.Int64
|
|
} // CHECK: Returns int: 11
|
|
|
|
// Test structs with mutating functions.
|
|
|
|
sil hidden @increment : $@convention(thin) (@inout Int32) -> () {
|
|
bb0(%0 : $*Int32):
|
|
%2 = integer_literal $Builtin.Int32, 1
|
|
%3 = begin_access [modify] [static] %0 : $*Int32
|
|
%4 = struct_element_addr %3 : $*Int32, #Int32._value
|
|
%5 = load %4 : $*Builtin.Int32
|
|
%6 = integer_literal $Builtin.Int1, -1
|
|
%7 = builtin "sadd_with_overflow_Int32"(%5 : $Builtin.Int32, %2 : $Builtin.Int32, %6 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%8 = tuple_extract %7 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%9 = tuple_extract %7 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %9 : $Builtin.Int1
|
|
%11 = struct $Int32 (%8 : $Builtin.Int32)
|
|
store %11 to %3 : $*Int32
|
|
%13 = tuple ()
|
|
end_access %3 : $*Int32
|
|
%15 = tuple ()
|
|
return %15 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretIntInOut
|
|
sil hidden @interpretIntInOut : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%0 = alloc_stack $Int32, var, name "i"
|
|
%1 = integer_literal $Builtin.Int32, 13
|
|
%2 = struct $Int32 (%1 : $Builtin.Int32)
|
|
store %2 to %0 : $*Int32
|
|
%4 = begin_access [modify] [static] %0 : $*Int32
|
|
%5 = function_ref @increment : $@convention(thin) (@inout Int32) -> ()
|
|
%6 = apply %5(%4) : $@convention(thin) (@inout Int32) -> ()
|
|
end_access %4 : $*Int32
|
|
|
|
%7 = load %0 : $*Int32
|
|
%8 = struct_extract %7 : $Int32, #Int32._value
|
|
dealloc_stack %0 : $*Int32
|
|
return %8 : $Builtin.Int32
|
|
} // CHECK: Returns int: 14
|
|
|
|
// CHECK-LABEL: @interpretNoAliasingTest
|
|
sil hidden @interpretNoAliasingTest : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%0 = alloc_stack $Int32, var, name "x"
|
|
%1 = integer_literal $Builtin.Int32, 1
|
|
%2 = struct $Int32 (%1 : $Builtin.Int32)
|
|
store %2 to %0 : $*Int32
|
|
%4 = alloc_stack $Int32, var, name "y"
|
|
%5 = begin_access [read] [static] %0 : $*Int32
|
|
store %2 to %4 : $*Int32
|
|
end_access %5 : $*Int32
|
|
%8 = begin_access [modify] [static] %0 : $*Int32
|
|
%9 = function_ref @increment : $@convention(thin) (@inout Int32) -> ()
|
|
%10 = apply %9(%8) : $@convention(thin) (@inout Int32) -> ()
|
|
end_access %8 : $*Int32
|
|
%12 = begin_access [read] [static] %0 : $*Int32
|
|
%13 = load %12 : $*Int32
|
|
end_access %12 : $*Int32
|
|
%15 = begin_access [read] [static] %4 : $*Int32
|
|
end_access %15 : $*Int32
|
|
%17 = struct_extract %13 : $Int32, #Int32._value
|
|
%18 = integer_literal $Builtin.Int1, -1
|
|
%19 = builtin "sadd_with_overflow_Int32"(%17 : $Builtin.Int32, %1 : $Builtin.Int32, %18 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%20 = tuple_extract %19 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%21 = tuple_extract %19 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %21 : $Builtin.Int1
|
|
dealloc_stack %4 : $*Int32
|
|
dealloc_stack %0 : $*Int32
|
|
return %20 : $Builtin.Int32
|
|
} // CHECK: Returns int: 3
|
|
|
|
// Test strings.
|
|
|
|
// CHECK-LABEL: @interpretStringLiteral
|
|
sil hidden @interpretStringLiteral : $@convention(thin) () -> Builtin.RawPointer {
|
|
bb0:
|
|
%0 = string_literal utf8 "plain string"
|
|
return %0 : $Builtin.RawPointer
|
|
} // CHECK: Returns string: "plain string"
|
|
|
|
// CHECK-LABEL: @interpretStringLiteralUnicode
|
|
sil hidden @interpretStringLiteralUnicode : $@convention(thin) () -> Builtin.RawPointer {
|
|
bb0:
|
|
%0 = string_literal utf8 "\u{1F496}"
|
|
return %0 : $Builtin.RawPointer
|
|
} // CHECK: Returns string: "💖"
|
|
|
|
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
// The semantics attribute is used by the interpreter.
|
|
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: @interpretStringInitIntrinsic
|
|
sil hidden @interpretStringInitIntrinsic : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = string_literal utf8 "plain string"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = integer_literal $Builtin.Int1, -1
|
|
%3 = metatype $@thin String.Type
|
|
%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
|
|
return %5 : $String
|
|
} // CHECK: Returns string: "plain string"
|
|
|
|
// TODO: Provide a more descriptive note that mentions the actual error.
|
|
// CHECK-LABEL: @interpretAndDiagnoseStringInitError
|
|
sil hidden @interpretAndDiagnoseStringInitError: $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = string_literal utf8 "\u{1F496}"
|
|
%1 = integer_literal $Builtin.Word, 1 // The byte length of the literal is wrong.
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
%3 = metatype $@thin String.Type
|
|
%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
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: operation with invalid operands encountered during evaluation
|
|
return %5 : $String
|
|
}
|
|
|
|
// String.append(_:_:)
|
|
// The semantics attribute is used by the interpreter.
|
|
sil [serialized] [_semantics "string.append"] @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
|
|
// CHECK-LABEL: @interpretStringAppend
|
|
sil @interpretStringAppend: $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = alloc_stack $String, var, name "a"
|
|
%1 = string_literal utf8 "a"
|
|
%2 = integer_literal $Builtin.Word, 1
|
|
%3 = integer_literal $Builtin.Int1, -1
|
|
%4 = metatype $@thin String.Type
|
|
%5 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = apply %5(%1, %2, %3, %4) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
store %6 to %0 : $*String
|
|
%8 = metatype $@thin String.Type
|
|
%9 = string_literal utf8 "b"
|
|
%10 = integer_literal $Builtin.Word, 1
|
|
%11 = integer_literal $Builtin.Int1, -1
|
|
%12 = metatype $@thin String.Type
|
|
%13 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%14 = apply %13(%9, %10, %11, %12) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%15 = begin_access [modify] [static] %0 : $*String
|
|
// function_ref static String.append (_:_:)
|
|
%16 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%17 = apply %16(%14, %15) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %15 : $*String
|
|
release_value %14 : $String
|
|
%20 = begin_access [read] [static] %0 : $*String
|
|
%21 = load %20 : $*String
|
|
retain_value %21 : $String
|
|
end_access %20 : $*String
|
|
destroy_addr %0 : $*String
|
|
dealloc_stack %0 : $*String
|
|
return %21 : $String
|
|
} // CHECK: Returns string: "ab"
|
|
|
|
// CHECK-LABEL: @interpretStringAppendUnicode
|
|
sil @interpretStringAppendUnicode: $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = alloc_stack $String, var, name "a"
|
|
%1 = string_literal utf8 "\u{1F1FA}"
|
|
%2 = integer_literal $Builtin.Word, 4
|
|
%3 = integer_literal $Builtin.Int1, 0
|
|
%4 = metatype $@thin String.Type
|
|
%5 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = apply %5(%1, %2, %3, %4) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
store %6 to %0 : $*String
|
|
%8 = metatype $@thin String.Type
|
|
%9 = string_literal utf8 "\u{1F1F8}"
|
|
%10 = integer_literal $Builtin.Word, 4
|
|
%11 = integer_literal $Builtin.Int1, 0
|
|
%12 = metatype $@thin String.Type
|
|
%13 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%14 = apply %13(%9, %10, %11, %12) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%15 = begin_access [modify] [static] %0 : $*String
|
|
// function_ref static String.+= infix(_:_:)
|
|
%16 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%17 = apply %16(%14, %15) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %15 : $*String
|
|
release_value %14 : $String
|
|
%20 = begin_access [read] [static] %0 : $*String
|
|
%21 = load %20 : $*String
|
|
retain_value %21 : $String
|
|
end_access %20 : $*String
|
|
destroy_addr %0 : $*String
|
|
dealloc_stack %0 : $*String
|
|
return %21 : $String
|
|
} // CHECK: Returns string: "🇺🇸"
|
|
|
|
// Test Enums.
|
|
|
|
public enum Shape {
|
|
case square(Int64)
|
|
case rectangle(Int64, Int64)
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretShapeArea
|
|
sil @interpretShapeArea : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = integer_literal $Builtin.Int64, 10
|
|
%2 = struct $Int64 (%1 : $Builtin.Int64)
|
|
%3 = enum $Shape, #Shape.square!enumelt, %2 : $Int64
|
|
switch_enum %3 : $Shape, case #Shape.square!enumelt: bb1, case #Shape.rectangle!enumelt: bb2
|
|
|
|
bb1(%4 : $Int64):
|
|
debug_value %4 : $Int64, let, name "side"
|
|
%5 = struct_extract %4 : $Int64, #Int64._value
|
|
%6 = struct_extract %4 : $Int64, #Int64._value
|
|
%7 = integer_literal $Builtin.Int1, -1
|
|
%8 = builtin "smul_with_overflow_Int64"(%5 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%10 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %10 : $Builtin.Int1
|
|
br bb3(%9 : $Builtin.Int64)
|
|
|
|
bb2(%15 : $(Int64, Int64)):
|
|
%16 = tuple_extract %15 : $(Int64, Int64), 0
|
|
%17 = tuple_extract %15 : $(Int64, Int64), 1
|
|
debug_value %16 : $Int64, let, name "length"
|
|
debug_value %17 : $Int64, let, name "width"
|
|
%20 = struct_extract %16 : $Int64, #Int64._value // user: %23
|
|
%21 = struct_extract %17 : $Int64, #Int64._value // user: %23
|
|
%22 = integer_literal $Builtin.Int1, -1
|
|
%23 = builtin "smul_with_overflow_Int64"(%20 : $Builtin.Int64, %21 : $Builtin.Int64, %22 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%24 = tuple_extract %23 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%25 = tuple_extract %23 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %25 : $Builtin.Int1
|
|
br bb3(%24 : $Builtin.Int64)
|
|
|
|
bb3(%30 : $Builtin.Int64):
|
|
return %30 : $Builtin.Int64
|
|
} // CHECK: Returns int: 100
|
|
|
|
// Test inject_enum_addr instruction.
|
|
|
|
public enum Direction {
|
|
case north
|
|
case south
|
|
case east
|
|
case west
|
|
}
|
|
|
|
sil @isNorth : $@convention(thin) (@in_guaranteed Direction) -> Builtin.Int32 {
|
|
bb0(%0 : $*Direction):
|
|
switch_enum_addr %0 : $*Direction, case #Direction.north!enumelt: bb1, default bb2
|
|
|
|
bb1:
|
|
%3 = integer_literal $Builtin.Int32, 1
|
|
br bb3(%3 : $Builtin.Int32)
|
|
|
|
bb2:
|
|
%6 = integer_literal $Builtin.Int32, 0
|
|
br bb3(%6 : $Builtin.Int32)
|
|
|
|
bb3(%9 : $Builtin.Int32):
|
|
return %9 : $Builtin.Int32
|
|
}
|
|
|
|
// CHECK: @interpretTestInjectEnumAddr
|
|
sil hidden @interpretTestInjectEnumAddr : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%1 = alloc_stack $Direction
|
|
inject_enum_addr %1 : $*Direction, #Direction.north!enumelt
|
|
%2 = function_ref @isNorth : $@convention(thin) (@in_guaranteed Direction) -> Builtin.Int32
|
|
%3 = apply %2(%1) : $@convention(thin) (@in_guaranteed Direction) -> Builtin.Int32
|
|
destroy_addr %1 : $*Direction
|
|
dealloc_stack %1 : $*Direction
|
|
return %3 : $Builtin.Int32
|
|
} // CHECK: Returns int: 1
|
|
|
|
// Test select_enum and select_enum_addr instructions.
|
|
|
|
// CHECK: @interpretTestSelectEnum
|
|
sil hidden @interpretTestSelectEnum : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%1 = enum $Direction, #Direction.north!enumelt
|
|
%2 = integer_literal $Builtin.Int32, 1
|
|
%3 = integer_literal $Builtin.Int32, 0
|
|
%4 = select_enum %1 : $Direction, case #Direction.north!enumelt: %2, default %3 : $Builtin.Int32
|
|
return %4 : $Builtin.Int32
|
|
} // CHECK: Returns int: 1
|
|
|
|
// CHECK: @interpretTestSelectEnumAddr
|
|
sil hidden @interpretTestSelectEnumAddr : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%1 = alloc_stack $Direction
|
|
inject_enum_addr %1 : $*Direction, #Direction.north!enumelt
|
|
%2 = integer_literal $Builtin.Int32, 1
|
|
%3 = integer_literal $Builtin.Int32, 0
|
|
%4 = select_enum_addr %1 : $*Direction, case #Direction.north!enumelt: %2, default %3 : $Builtin.Int32
|
|
destroy_addr %1 : $*Direction
|
|
dealloc_stack %1 : $*Direction
|
|
return %4 : $Builtin.Int32
|
|
} // CHECK: Returns int: 1
|
|
|
|
// Test calling conventions.
|
|
|
|
// Test struct with a string property. The struct will be passed and returned
|
|
// @guaranteed when its methods are called.
|
|
|
|
struct S {
|
|
var prop: String
|
|
}
|
|
|
|
sil hidden @initS : $@convention(thin) () -> @owned S {
|
|
bb0:
|
|
%2 = string_literal utf8 "something"
|
|
%3 = integer_literal $Builtin.Word, 9
|
|
%4 = integer_literal $Builtin.Int1, -1
|
|
%5 = metatype $@thin String.Type
|
|
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
|
|
%6 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%7 = apply %6(%2, %3, %4, %5) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%12 = struct $S (%7 : $String)
|
|
retain_value %12 : $S
|
|
return %12 : $S
|
|
}
|
|
|
|
sil @getProp : $@convention(method) (@guaranteed S) -> @owned String {
|
|
bb0(%0 : $S):
|
|
%2 = struct_extract %0 : $S, #S.prop
|
|
retain_value %2 : $String
|
|
return %2 : $String
|
|
}
|
|
|
|
// CHECK: @interpretGuaranteedConvention
|
|
sil @interpretGuaranteedConvention : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%1 = function_ref @initS : $@convention(thin) () -> @owned S
|
|
%2 = apply %1() : $@convention(thin) () -> @owned S
|
|
%4 = function_ref @getProp : $@convention(method) (@guaranteed S) -> @owned String
|
|
%5 = apply %4(%2) : $@convention(method) (@guaranteed S) -> @owned String
|
|
release_value %2 : $S
|
|
return %5 : $String
|
|
} // CHECK: Returns string: "something"
|
|
|
|
|
|
// TODO: add tests for generic functions, generic structs and generic enums.
|
|
|
|
// A composite test that mimics the format specifier construction used by
|
|
// os log APIs.
|
|
|
|
enum IntFormat {
|
|
case decimal
|
|
case hex
|
|
case octal
|
|
}
|
|
|
|
// getIntegerFormatSpecifier(IntFormat:isPrivate:bitWidth:isSigned:)
|
|
sil @getIntegerFormatSpecifier : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String {
|
|
bb0(%0 : $IntFormat, %1 : $Bool, %2 : $Int64, %3 : $Bool):
|
|
%10 = alloc_stack $String, var, name "formatSpecifier"
|
|
%11 = struct_extract %1 : $Bool, #Bool._value
|
|
cond_br %11, bb1, bb2
|
|
|
|
bb1:
|
|
%13 = string_literal utf8 "%{private}"
|
|
%14 = integer_literal $Builtin.Word, 10
|
|
%15 = integer_literal $Builtin.Int1, -1
|
|
%16 = metatype $@thin String.Type
|
|
%17 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%18 = apply %17(%13, %14, %15, %16) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
br bb3(%18 : $String)
|
|
|
|
bb2:
|
|
%20 = string_literal utf8 "%{public}"
|
|
%21 = integer_literal $Builtin.Word, 9
|
|
%22 = integer_literal $Builtin.Int1, -1
|
|
%23 = metatype $@thin String.Type
|
|
%24 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%25 = apply %24(%20, %21, %22, %23) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
br bb3(%25 : $String)
|
|
|
|
bb3(%27 : $String):
|
|
store %27 to %10 : $*String
|
|
%29 = integer_literal $Builtin.Int64, 64
|
|
%30 = struct_extract %2 : $Int64, #Int64._value
|
|
%31 = builtin "cmp_eq_Int64"(%30 : $Builtin.Int64, %29 : $Builtin.Int64) : $Builtin.Int1
|
|
%32 = struct $Bool (%31 : $Builtin.Int1)
|
|
%33 = struct_extract %32 : $Bool, #Bool._value
|
|
cond_br %33, bb4, bb5
|
|
|
|
bb4:
|
|
%35 = metatype $@thin String.Type
|
|
%36 = string_literal utf8 "ll"
|
|
%37 = integer_literal $Builtin.Word, 2
|
|
%38 = integer_literal $Builtin.Int1, -1
|
|
%39 = metatype $@thin String.Type
|
|
%40 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%41 = apply %40(%36, %37, %38, %39) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%42 = begin_access [modify] [static] %10 : $*String
|
|
%43 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%44 = apply %43(%41, %42) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %42 : $*String
|
|
release_value %41 : $String
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
switch_enum %0 : $IntFormat, case #IntFormat.hex!enumelt: bb7, case #IntFormat.octal!enumelt: bb8, default bb9
|
|
|
|
bb7:
|
|
%50 = metatype $@thin String.Type
|
|
%51 = string_literal utf8 "x"
|
|
%52 = integer_literal $Builtin.Word, 1
|
|
%53 = integer_literal $Builtin.Int1, -1
|
|
%54 = metatype $@thin String.Type
|
|
%55 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%56 = apply %55(%51, %52, %53, %54) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%57 = begin_access [modify] [static] %10 : $*String
|
|
%58 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%59 = apply %58(%56, %57) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %57 : $*String
|
|
release_value %56 : $String
|
|
br bb13
|
|
|
|
bb8:
|
|
%63 = metatype $@thin String.Type
|
|
%64 = string_literal utf8 "o"
|
|
%65 = integer_literal $Builtin.Word, 1
|
|
%66 = integer_literal $Builtin.Int1, -1
|
|
%67 = metatype $@thin String.Type
|
|
%68 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%69 = apply %68(%64, %65, %66, %67) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%70 = begin_access [modify] [static] %10 : $*String
|
|
%71 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%72 = apply %71(%69, %70) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %70 : $*String
|
|
release_value %69 : $String
|
|
br bb13
|
|
|
|
bb9:
|
|
%76 = metatype $@thin String.Type
|
|
%77 = struct_extract %3 : $Bool, #Bool._value
|
|
cond_br %77, bb10, bb11
|
|
|
|
bb10:
|
|
%79 = string_literal utf8 "d"
|
|
%80 = integer_literal $Builtin.Word, 1
|
|
%81 = integer_literal $Builtin.Int1, -1
|
|
%82 = metatype $@thin String.Type
|
|
%83 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%84 = apply %83(%79, %80, %81, %82) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
br bb12(%84 : $String)
|
|
|
|
bb11:
|
|
%86 = string_literal utf8 "u"
|
|
%87 = integer_literal $Builtin.Word, 1
|
|
%88 = integer_literal $Builtin.Int1, -1
|
|
%89 = metatype $@thin String.Type
|
|
%90 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%91 = apply %90(%86, %87, %88, %89) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
br bb12(%91 : $String)
|
|
|
|
bb12(%93 : $String):
|
|
%94 = begin_access [modify] [static] %10 : $*String
|
|
%95 = function_ref @$sSS6appendyySSF : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
%96 = apply %95(%93, %94) : $@convention(method) (@guaranteed String, @inout String) -> ()
|
|
end_access %94 : $*String
|
|
release_value %93 : $String
|
|
br bb13
|
|
|
|
bb13:
|
|
%100 = begin_access [read] [static] %10 : $*String
|
|
%101 = load %100 : $*String
|
|
retain_value %101 : $String
|
|
end_access %100 : $*String
|
|
destroy_addr %10 : $*String
|
|
dealloc_stack %10 : $*String
|
|
return %101 : $String
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretGetPrivateInt64FormatString
|
|
sil @interpretGetPrivateInt64FormatString : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%2 = metatype $@thin IntFormat.Type
|
|
%3 = enum $IntFormat, #IntFormat.decimal!enumelt
|
|
%4 = integer_literal $Builtin.Int1, -1
|
|
%5 = struct $Bool (%4 : $Builtin.Int1)
|
|
%6 = integer_literal $Builtin.Int64, 64
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, -1
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
%10 = function_ref @getIntegerFormatSpecifier : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
%11 = apply %10(%3, %5, %7, %9) : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
return %11 : $String
|
|
} // CHECK: Returns string: "%{private}lld"
|
|
|
|
// CHECK-LABEL: @interpretGetPrivateHexInt64FormatString
|
|
sil @interpretGetPrivateHexInt64FormatString : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%2 = metatype $@thin IntFormat.Type
|
|
%3 = enum $IntFormat, #IntFormat.hex!enumelt
|
|
%4 = integer_literal $Builtin.Int1, -1
|
|
%5 = struct $Bool (%4 : $Builtin.Int1)
|
|
%6 = integer_literal $Builtin.Int64, 64
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, -1
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
%10 = function_ref @getIntegerFormatSpecifier : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
%11 = apply %10(%3, %5, %7, %9) : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
return %11 : $String
|
|
} // CHECK: Returns string: "%{private}llx"
|
|
|
|
// CHECK-LABEL: @interpretGetPublicOctalInt32FormatString
|
|
sil @interpretGetPublicOctalInt32FormatString : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%2 = metatype $@thin IntFormat.Type
|
|
%3 = enum $IntFormat, #IntFormat.octal!enumelt
|
|
%4 = integer_literal $Builtin.Int1, 0
|
|
%5 = struct $Bool (%4 : $Builtin.Int1)
|
|
%6 = integer_literal $Builtin.Int64, 32
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, -1
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
%10 = function_ref @getIntegerFormatSpecifier : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
%11 = apply %10(%3, %5, %7, %9) : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
return %11 : $String
|
|
} // CHECK: Returns string: "%{public}o"
|
|
|
|
// CHECK-LABEL: @interpretGetUInt64FormatString
|
|
sil @interpretGetUInt64FormatString : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%2 = metatype $@thin IntFormat.Type
|
|
%3 = enum $IntFormat, #IntFormat.decimal!enumelt
|
|
%4 = integer_literal $Builtin.Int1, 0
|
|
%5 = struct $Bool (%4 : $Builtin.Int1)
|
|
%6 = integer_literal $Builtin.Int64, 64
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, 0
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
%10 = function_ref @getIntegerFormatSpecifier : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
%11 = apply %10(%3, %5, %7, %9) : $@convention(thin) (IntFormat, Bool, Int64, Bool) -> @owned String
|
|
return %11 : $String
|
|
} // CHECK: Returns string: "%{public}llu"
|
|
|
|
// String.percentEscapedString.getter
|
|
// The semantics attribute is used by the interpreter.
|
|
sil [serialized] [readonly] [_semantics "string.escapePercent.get"] @$sSS14OSLogPrototypeE20percentEscapedStringSSvg : $@convention(method) (@guaranteed String) -> @owned String
|
|
|
|
// CHECK-LABEL: @interpretStringPercentEscape
|
|
sil @interpretStringPercentEscape : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%1 = string_literal utf8 "a%"
|
|
%2 = integer_literal $Builtin.Word, 2
|
|
%3 = integer_literal $Builtin.Int1, -1
|
|
%4 = metatype $@thin String.Type
|
|
%5 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = apply %5(%1, %2, %3, %4) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%8 = function_ref @$sSS14OSLogPrototypeE20percentEscapedStringSSvg : $@convention(method) (@guaranteed String) -> @owned String
|
|
%9 = apply %8(%6) : $@convention(method) (@guaranteed String) -> @owned String
|
|
return %9 : $String
|
|
} // CHECK: Returns string: "a%%"
|
|
|
|
// CHECK-LABEL: @interpretEscapeMultiplePercent
|
|
sil @interpretEscapeMultiplePercent : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%1 = string_literal utf8 "%%%a% %%b%"
|
|
%2 = integer_literal $Builtin.Word, 10
|
|
%3 = integer_literal $Builtin.Int1, -1
|
|
%4 = metatype $@thin String.Type
|
|
%5 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%6 = apply %5(%1, %2, %3, %4) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String
|
|
%8 = function_ref @$sSS14OSLogPrototypeE20percentEscapedStringSSvg : $@convention(method) (@guaranteed String) -> @owned String
|
|
%9 = apply %8(%6) : $@convention(method) (@guaranteed String) -> @owned String
|
|
return %9 : $String
|
|
} // CHECK: Returns string: "%%%%%%a%% %%%%b%%"
|
|
|
|
// Tests for Ownership SIL.
|
|
|
|
// CHECK-LABEL: @interpretDestructureInt64
|
|
sil [ossa] @interpretDestructureInt64 : $@convention(thin) () -> Builtin.Int64 {
|
|
%1 = integer_literal $Builtin.Int64, 12
|
|
%2 = struct $Int64 (%1 : $Builtin.Int64)
|
|
%3 = destructure_struct %2 : $Int64
|
|
return %3 : $Builtin.Int64
|
|
} // CHECK: Returns int: 12
|
|
|
|
struct IntPair {
|
|
var first: Builtin.Int64
|
|
var second: Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretIntPairStruct
|
|
sil [ossa] @interpretIntPairStruct : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 17
|
|
%1 = integer_literal $Builtin.Int64, 34
|
|
%2 = struct $IntPair (%0: $Builtin.Int64, %1: $Builtin.Int64)
|
|
(%3, %4) = destructure_struct %2 : $IntPair
|
|
return %4 : $Builtin.Int64
|
|
} // CHECK: Returns int: 34
|
|
|
|
sil [ossa] @constructCustomStructOSSA : $@convention(thin) () -> CustomStruct {
|
|
bb0:
|
|
%1 = integer_literal $Builtin.Int64, 11
|
|
%2 = struct $Int64 (%1 : $Builtin.Int64)
|
|
%3 = integer_literal $Builtin.Int64, 12
|
|
%4 = struct $Int64 (%3 : $Builtin.Int64)
|
|
%6 = integer_literal $Builtin.Int64, 13
|
|
%7 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%8 = integer_literal $Builtin.Int1, 0
|
|
%9 = struct $Bool (%8 : $Builtin.Int1)
|
|
|
|
%10 = struct $InnerStruct (%7 : $Int64, %9 : $Bool)
|
|
%11 = tuple (%2 : $Int64, %4 : $Int64)
|
|
%12 = struct $CustomStruct (%11 : $(Int64, Int64), %10 : $InnerStruct)
|
|
return %12 : $CustomStruct
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretCustomStructOSSA
|
|
sil [ossa] @interpretCustomStructOSSA : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%1 = function_ref @constructCustomStructOSSA : $@convention(thin) () -> CustomStruct
|
|
%2 = apply %1() : $@convention(thin) () -> CustomStruct
|
|
(%3, %4) = destructure_struct %2 : $CustomStruct
|
|
(%5, %6) = destructure_tuple %3 : $(Int64, Int64)
|
|
(%7, %8) = destructure_struct %4 : $InnerStruct
|
|
%9 = destructure_struct %5 : $Int64
|
|
%10 = destructure_struct %6 : $Int64
|
|
%11 = destructure_struct %7 : $Int64
|
|
%12 = destructure_struct %8 : $Bool
|
|
cond_fail %12 : $Builtin.Int1
|
|
|
|
%13 = integer_literal $Builtin.Int1, -1
|
|
%14 = builtin "sadd_with_overflow_Int64"(%9 : $Builtin.Int64, %10 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
(%15, %16) = destructure_tuple %14 : $(Builtin.Int64, Builtin.Int1)
|
|
cond_fail %16 : $Builtin.Int1
|
|
|
|
%17 = builtin "sadd_with_overflow_Int64"(%15 : $Builtin.Int64, %11 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
(%18, %19) = destructure_tuple %17 : $(Builtin.Int64, Builtin.Int1)
|
|
cond_fail %19 : $Builtin.Int1
|
|
return %18 : $Builtin.Int64
|
|
} // CHECK: Returns int: 36
|
|
|
|
// Tests for builtin "ptrtoint_Word", which is supported only for string
|
|
// constants in order to handle 'StaticString' construction.
|
|
|
|
// CHECK-LABEL: @interpretPtrToInt
|
|
sil @interpretPtrToInt : $@convention(thin) () -> Builtin.Word {
|
|
%0 = string_literal utf8 "Fatal error"
|
|
%1 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
|
|
return %1 : $Builtin.Word
|
|
} // CHECK: Returns string: "Fatal error"
|
|
|
|
// CHECK-LABEL: @interpretStaticStringInit
|
|
sil @interpretStaticStringInit : $@convention(thin) () -> Builtin.Word {
|
|
%0 = string_literal utf8 "static error message"
|
|
%1 = integer_literal $Builtin.Word, 11
|
|
%2 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
|
|
%3 = integer_literal $Builtin.Int8, 2
|
|
%4 = struct $StaticString (%2 : $Builtin.Word, %1 : $Builtin.Word, %3 : $Builtin.Int8)
|
|
%5 = struct_extract %4 : $StaticString, #StaticString._startPtrOrData
|
|
return %5 : $Builtin.Word
|
|
} // CHECK: Returns string: "static error message"
|
|
|
|
// Tests for builtin "assert_configuration". Constant evaluator evaluates this
|
|
// builtin to 0, meaning that the configuration is "debug".
|
|
|
|
// CHECK-LABEL: @interpretAssertConfiguration
|
|
sil @interpretAssertConfiguration : $@convention(thin) () -> Builtin.Int32 {
|
|
%0 = builtin "assert_configuration"() : $Builtin.Int32
|
|
return %0 : $Builtin.Int32
|
|
} // CHECK: Returns int: 0
|
|
|
|
// Tests for "assertionFailure" stdlib functions. Such functions have the
|
|
// @_semantics attribute: "programtermination_point"
|
|
|
|
sil [noinline] [_semantics "programtermination_point"] [canonical] @$assertionFailure : $@convention(thin) (StaticString, StaticString, UInt64) -> Never
|
|
|
|
// CHECK-LABEL: @interpretAssertionFailure
|
|
sil @interpretAssertionFailure : $@convention(thin) () -> Never {
|
|
// Construct error prefix.
|
|
%0 = string_literal utf8 "error-prefix"
|
|
%1 = integer_literal $Builtin.Word, 12
|
|
%2 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
|
|
%3 = integer_literal $Builtin.Int8, 2
|
|
%4 = struct $StaticString (%2 : $Builtin.Word, %1 : $Builtin.Word, %3 : $Builtin.Int8)
|
|
|
|
// Construct error message.
|
|
%10 = string_literal utf8 "message"
|
|
%11 = integer_literal $Builtin.Word, 7
|
|
%12 = builtin "ptrtoint_Word"(%10 : $Builtin.RawPointer) : $Builtin.Word
|
|
%13 = integer_literal $Builtin.Int8, 2
|
|
%14 = struct $StaticString (%12 : $Builtin.Word, %11 : $Builtin.Word, %13 : $Builtin.Int8)
|
|
|
|
// Construct line number.
|
|
%20 = integer_literal $Builtin.Int64, 1208
|
|
%21 = struct $UInt64 (%20 : $Builtin.Int64)
|
|
|
|
%22 = function_ref @$assertionFailure : $@convention(thin) (StaticString, StaticString, UInt64) -> Never
|
|
%23 = apply %22(%4, %14, %21) : $@convention(thin) (StaticString, StaticString, UInt64) -> Never
|
|
// CHECK: {{.*}}:[[@LINE-1]]:{{.*}}: note: error-prefix: message
|
|
unreachable
|
|
}
|
|
|
|
// Tests for arrays.
|
|
|
|
// Array.init()
|
|
sil [serialized] [_semantics "array.init.empty"] @$sS2ayxGycfC : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
|
|
// _allocateUninitializedArray<A>(_:)
|
|
sil [serialized] [always_inline] [_semantics "array.uninitialized_intrinsic"] @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
|
|
// CHECK-LABEL: @interpretArrayInit
|
|
sil @interpretArrayInit : $@convention(thin) () -> @owned Array<Int> {
|
|
bb0:
|
|
%0 = metatype $@thin Array<Int>.Type
|
|
// function_ref Array.init()
|
|
%1 = function_ref @$sS2ayxGycfC : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
%2 = apply %1<Int>(%0) : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
return %2 : $Array<Int>
|
|
} // CHECK: Returns Array<Int>
|
|
// CHECK: size: 0 contents []
|
|
|
|
// CHECK-LABEL: @interpretEmptyArrayLiteral
|
|
sil [ossa] @interpretEmptyArrayLiteral : $@convention(thin) () -> @owned Array<String> {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Word, 0
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%1 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%2 = apply %1<String>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
(%3, %4) = destructure_tuple %2 : $(Array<String>, Builtin.RawPointer)
|
|
return %3 : $Array<String>
|
|
} // CHECK: Returns Array<String>
|
|
// CHECK: size: 0 contents []
|
|
|
|
sil [ossa] @initializeArrayWithLiterals : $@convention(thin) () -> @owned Array<Int64> {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 11 // element 1
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = integer_literal $Builtin.Int64, 12 // element 2
|
|
%3 = struct $Int64 (%2 : $Builtin.Int64)
|
|
%4 = integer_literal $Builtin.Int64, 14 // element 3
|
|
%5 = struct $Int64 (%4 : $Builtin.Int64)
|
|
|
|
%6 = integer_literal $Builtin.Word, 3 // array literal size
|
|
// function_ref _allocateUninitializedArray<A>(_:)
|
|
%7 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
%8 = apply %7<Int64>(%6) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
|
|
(%9, %10) = destructure_tuple %8 : $(Array<Int64>, Builtin.RawPointer)
|
|
%11 = pointer_to_address %10 : $Builtin.RawPointer to [strict] $*Int64
|
|
store %1 to [trivial] %11 : $*Int64
|
|
%13 = integer_literal $Builtin.Word, 1 // Index: 1
|
|
%14 = index_addr %11 : $*Int64, %13 : $Builtin.Word
|
|
store %3 to [trivial] %14 : $*Int64
|
|
%16 = integer_literal $Builtin.Word, 2 // Index: 2
|
|
%17 = index_addr %11 : $*Int64, %16 : $Builtin.Word
|
|
store %5 to [trivial] %17 : $*Int64
|
|
return %9 : $Array<Int64>
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretArrayLiteral
|
|
sil [ossa] @interpretArrayLiteral : $@convention(thin) () -> @owned Array<Int64> {
|
|
bb0:
|
|
%7 = function_ref @initializeArrayWithLiterals : $@convention(thin) () -> @owned Array<Int64>
|
|
%8 = apply %7() : $@convention(thin) () -> @owned Array<Int64>
|
|
return %8 : $Array<Int64>
|
|
} // CHECK: Returns Array<Int64>
|
|
// CHECK: size: 3
|
|
// CHECK: agg: 1 elt: int: 11
|
|
// CHECK: agg: 1 elt: int: 12
|
|
// CHECK: agg: 1 elt: int: 14
|
|
|
|
// Array.append(_:)
|
|
sil [serialized] [_semantics "array.append_element"] @$sSa6appendyyxnF : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
|
|
// CHECK-LABEL: @interpretArrayAppend
|
|
sil [ossa] @interpretArrayAppend : $@convention(thin) () -> @owned Array<Int64> {
|
|
%0 = integer_literal $Builtin.Int64, 71
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = alloc_stack $Array<Int64>, var, name "a"
|
|
%3 = metatype $@thin Array<Int64>.Type
|
|
// function_ref Array.init()
|
|
%4 = function_ref @$sS2ayxGycfC : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
%5 = apply %4<Int64>(%3) : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
store %5 to [init] %2 : $*Array<Int64>
|
|
%10 = alloc_stack $Int64
|
|
store %1 to [trivial] %10 : $*Int64
|
|
// function_ref Array.append(_:)
|
|
%13 = function_ref @$sSa6appendyyxnF : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
%14 = apply %13<Int64>(%10, %2) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
dealloc_stack %10 : $*Int64
|
|
%18 = load [copy] %2 : $*Array<Int64>
|
|
destroy_addr %2 : $*Array<Int64>
|
|
dealloc_stack %2 : $*Array<Int64>
|
|
return %18 : $Array<Int64>
|
|
} // CHECK: Returns Array<Int64>
|
|
// CHECK: size: 1
|
|
// CHECK: agg: 1 elt: int: 71
|
|
|
|
// CHECK-LABEL: @interpretArrayAppendNonEmpty
|
|
sil [ossa] @interpretArrayAppendNonEmpty : $@convention(thin) () -> @owned Array<Int64> {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 100
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = alloc_stack $Array<Int64>, var, name "a"
|
|
%3 = metatype $@thin Array<Int64>.Type
|
|
%4 = function_ref @initializeArrayWithLiterals : $@convention(thin) () -> @owned Array<Int64>
|
|
%5 = apply %4() : $@convention(thin) () -> @owned Array<Int64>
|
|
store %5 to [init] %2 : $*Array<Int64>
|
|
%10 = alloc_stack $Int64
|
|
store %1 to [trivial] %10 : $*Int64
|
|
// function_ref Array.append(_:)
|
|
%13 = function_ref @$sSa6appendyyxnF : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
%14 = apply %13<Int64>(%10, %2) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
dealloc_stack %10 : $*Int64
|
|
%18 = load [copy] %2 : $*Array<Int64>
|
|
destroy_addr %2 : $*Array<Int64>
|
|
dealloc_stack %2 : $*Array<Int64>
|
|
return %18 : $Array<Int64>
|
|
} // CHECK: Returns Array<Int64>
|
|
// CHECK: size: 4
|
|
// CHECK: agg: 1 elt: int: 11
|
|
// CHECK: agg: 1 elt: int: 12
|
|
// CHECK: agg: 1 elt: int: 14
|
|
// CHECK: agg: 1 elt: int: 100
|
|
|
|
struct StructContainingArray {
|
|
var array: [Int64]
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretArrayAppendViaStructElementAddr
|
|
sil [ossa] @interpretArrayAppendViaStructElementAddr : $@convention(thin) () -> @owned StructContainingArray {
|
|
bb0:
|
|
%3 = metatype $@thin Array<Int64>.Type
|
|
// function_ref Array.init()
|
|
%4 = function_ref @$sS2ayxGycfC : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
%5 = apply %4<Int64>(%3) : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
%6 = struct $StructContainingArray (%5 : $Array<Int64>)
|
|
|
|
%7 = alloc_stack $StructContainingArray, var, name "s"
|
|
store %6 to [init] %7 : $*StructContainingArray
|
|
%8 = struct_element_addr %7 : $*StructContainingArray, #StructContainingArray.array
|
|
|
|
%9 = integer_literal $Builtin.Int64, 105
|
|
%10 = struct $Int64 (%9 : $Builtin.Int64)
|
|
%11 = alloc_stack $Int64
|
|
store %10 to [trivial] %11 : $*Int64
|
|
|
|
// function_ref Array.append(_:)
|
|
%13 = function_ref @$sSa6appendyyxnF : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
%14 = apply %13<Int64>(%11, %8) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
dealloc_stack %11 : $*Int64
|
|
|
|
%18 = load [copy] %7 : $*StructContainingArray
|
|
destroy_addr %7 : $*StructContainingArray
|
|
dealloc_stack %7 : $*StructContainingArray
|
|
return %18 : $StructContainingArray
|
|
} // CHECK: agg: 1 elt: Array<Int64>:
|
|
// CHECK: size: 1
|
|
// CHECK: agg: 1 elt: int: 105
|
|
|
|
/// Test appending of a static string to an array. The construction of a static
|
|
/// string is a bit complicated due to the use of instructions like "ptrtoint".
|
|
/// This tests that array append works with such complex constant values as well.
|
|
// CHECK-LABEL: @interpretArrayAppendStaticString
|
|
sil @interpretArrayAppendStaticString : $@convention(thin) () -> @owned Array<StaticString> {
|
|
%0 = string_literal utf8 "constant" // string to be appended.
|
|
|
|
// Initialize an empty array
|
|
%2 = alloc_stack $Array<StaticString>, var, name "a"
|
|
%3 = metatype $@thin Array<StaticString>.Type
|
|
// function_ref Array.init()
|
|
%4 = function_ref @$sS2ayxGycfC : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
%5 = apply %4<StaticString>(%3) : $@convention(method) <τ_0_0> (@thin Array<τ_0_0>.Type) -> @owned Array<τ_0_0>
|
|
store %5 to %2 : $*Array<StaticString>
|
|
|
|
// Initialize a static string.
|
|
%6 = integer_literal $Builtin.Word, 8
|
|
%7 = builtin "ptrtoint_Word"(%0 : $Builtin.RawPointer) : $Builtin.Word
|
|
%8 = integer_literal $Builtin.Int8, 2
|
|
%9 = struct $StaticString (%7 : $Builtin.Word, %6 : $Builtin.Word, %8 : $Builtin.Int8)
|
|
|
|
%10 = alloc_stack $StaticString
|
|
store %9 to %10 : $*StaticString
|
|
// function_ref Array.append(_:)
|
|
%13 = function_ref @$sSa6appendyyxnF : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
%14 = apply %13<StaticString>(%10, %2) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout Array<τ_0_0>) -> ()
|
|
dealloc_stack %10 : $*StaticString
|
|
%18 = load %2 : $*Array<StaticString>
|
|
destroy_addr %2 : $*Array<StaticString>
|
|
dealloc_stack %2 : $*Array<StaticString>
|
|
return %18 : $Array<StaticString>
|
|
} // CHECK: Returns Array<StaticString>
|
|
// CHECK: size: 1
|
|
// CHECK: string: "constant"
|
|
|
|
// Test partial apply and closure creation.
|
|
|
|
sil private @closure1 : $@convention(thin) (Int32) -> Int32 {
|
|
bb0(%0 : $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretPartialApply
|
|
sil @interpretPartialApply: $@convention(thin) () -> @owned @callee_guaranteed () -> Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 81
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
%2 = function_ref @closure1 : $@convention(thin) (Int32) -> Int32
|
|
%3 = partial_apply [callee_guaranteed] %2(%1) : $@convention(thin) (Int32) -> Int32
|
|
return %3 : $@callee_guaranteed () -> Int32
|
|
} // CHECK: Returns closure: target: closure1 captures
|
|
// CHECK: %1
|
|
// CHECK: values:
|
|
// CHECK: int: 81
|
|
|
|
sil private @closure2 : $@convention(thin) (Int32, Int32) -> Int32 {
|
|
bb0(%0 : $Int32, %1: $Int32):
|
|
return %0 : $Int32
|
|
}
|
|
|
|
sil private @closure3 : $@convention(thin) (@guaranteed @callee_guaranteed (Int32) -> Int32) -> Int32 {
|
|
bb0(%0 : $@callee_guaranteed (Int32) -> Int32):
|
|
%3 = integer_literal $Builtin.Int32, 19
|
|
%4 = struct $Int32 (%3 : $Builtin.Int32)
|
|
%5 = apply %0(%4) : $@callee_guaranteed (Int32) -> Int32
|
|
return %5 : $Int32
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretPartialApplyChain
|
|
sil @interpretPartialApplyChain: $@convention(thin) () -> @owned @callee_guaranteed () -> Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 991
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
%2 = function_ref @closure2 : $@convention(thin) (Int32, Int32) -> Int32
|
|
%3 = partial_apply [callee_guaranteed] %2(%1) : $@convention(thin) (Int32, Int32) -> Int32
|
|
%5 = function_ref @closure3 : $@convention(thin) (@guaranteed @callee_guaranteed (Int32) -> Int32) -> Int32
|
|
strong_retain %3 : $@callee_guaranteed (Int32) -> Int32
|
|
%7 = partial_apply [callee_guaranteed] %5(%3) : $@convention(thin) (@guaranteed @callee_guaranteed (Int32) -> Int32) -> Int32
|
|
strong_release %3 : $@callee_guaranteed (Int32) -> Int32
|
|
return %7 : $@callee_guaranteed () -> Int32
|
|
} // CHECK: Returns closure: target: closure3 captures
|
|
// CHECK: %3
|
|
// CHECK: values:
|
|
// CHECK: closure: target: closure2 captures
|
|
// CHECK: %1
|
|
// CHECK: values:
|
|
// CHECK: int: 991
|
|
|
|
|
|
sil private @closure4 : $@convention(thin) () -> Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 71
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
return %1 : $Int64
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretThinToThickFunction
|
|
sil @interpretThinToThickFunction: $@convention(thin) () -> @owned @callee_guaranteed () -> Int64 {
|
|
bb0:
|
|
%0 = function_ref @closure4 : $@convention(thin) () -> Int64
|
|
%3 = thin_to_thick_function %0 : $@convention(thin) () -> Int64 to $@callee_guaranteed () -> Int64
|
|
return %3 : $@callee_guaranteed () -> Int64
|
|
} // CHECK: Returns closure: target: closure4 captures
|
|
// CHECK-NEXT: values:
|
|
|
|
// Tests for checked cast instruction.
|
|
|
|
sil [ossa] @testMetatypeCast : $@convention(thin) <T> (@thick T.Type) -> Builtin.Int1 {
|
|
bb0(%0 : $@thick T.Type):
|
|
checked_cast_br T.Type in %0 : $@thick T.Type to Int64.Type, bb1, bb2
|
|
|
|
bb1(%3 : $@thick Int64.Type):
|
|
%4 = metatype $@thin Int64.Type
|
|
%5 = integer_literal $Builtin.Int1, -1
|
|
br bb3(%5 : $Builtin.Int1)
|
|
|
|
bb2(%7 : $@thick T.Type):
|
|
%8 = integer_literal $Builtin.Int1, 0
|
|
br bb3(%8 : $Builtin.Int1)
|
|
|
|
bb3(%10 : $Builtin.Int1):
|
|
return %10 : $Builtin.Int1
|
|
}
|
|
|
|
// CHECK-LABEL: @interpretMetatypeCast
|
|
sil [ossa] @interpretMetatypeCast : $@convention(thin) () -> Builtin.Int1 {
|
|
bb0:
|
|
%1 = metatype $@thick Int64.Type
|
|
%2 = function_ref @testMetatypeCast : $@convention(thin) <τ_0_0> (@thick τ_0_0.Type) -> Builtin.Int1
|
|
%3 = apply %2<Int64>(%1) : $@convention(thin) <τ_0_0> (@thick τ_0_0.Type) -> Builtin.Int1
|
|
return %3 : $Builtin.Int1
|
|
} // CHECK: Returns int: -1
|
|
|
|
// CHECK-LABEL: @interpretBinaryIntegerDescription
|
|
sil [ossa] @interpretBinaryIntegerDescription : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, -10
|
|
%1 = struct $Int64 (%0 : $Builtin.Int64)
|
|
%2 = alloc_stack $Int64
|
|
store %1 to [trivial] %2 : $*Int64
|
|
%4 = function_ref @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String
|
|
%5 = apply %4<Int64>(%2) : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String
|
|
dealloc_stack %2 : $*Int64
|
|
return %5 : $String
|
|
} // CHECK: Returns string: "-10"
|
|
|
|
sil [_semantics "binaryInteger.description"] @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String
|
|
|
|
// CHECK-LABEL: @interpretUnsignedBinaryIntegerDescription
|
|
sil [ossa] @interpretUnsignedBinaryIntegerDescription : $@convention(thin) () -> @owned String {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 0xffffffffffffffff
|
|
%1 = struct $UInt64 (%0 : $Builtin.Int64)
|
|
%2 = alloc_stack $UInt64
|
|
store %1 to [trivial] %2 : $*UInt64
|
|
%4 = function_ref @binaryIntegerDescription : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String
|
|
%5 = apply %4<UInt64>(%2) : $@convention(method) <τ_0_0 where τ_0_0 : BinaryInteger> (@in_guaranteed τ_0_0) -> @owned String
|
|
dealloc_stack %2 : $*UInt64
|
|
return %5 : $String
|
|
} // CHECK: Returns string: "18446744073709551615"
|
|
|
|
// CHECK-LABEL: @interpretTsanInstrumentationSkip
|
|
sil [ossa] @interpretTsanInstrumentationSkip : $@convention(thin) () -> Builtin.Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 23
|
|
%1 = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %1 : $*Builtin.Int32
|
|
// This builtin should be skipped and should not affect the value of the argument
|
|
%2 = builtin "tsanInoutAccess"(%1 : $*Builtin.Int32) : $()
|
|
%3 = load [trivial] %1 : $*Builtin.Int32
|
|
dealloc_stack %1 : $*Builtin.Int32
|
|
return %3 : $Builtin.Int32
|
|
} // CHECK: Returns int: 23
|
|
|
|
// CHECK-LABEL: @interpretCoverageInstrumentationSkip
|
|
sil @interpretCoverageInstrumentationSkip : $@convention(thin) () -> Builtin.Int64 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int64, 25
|
|
// This builtin should be skipped
|
|
increment_profiler_counter 0, "$s2os6LoggerV3logyyAA12OSLogMessageVF", num_counters 1, hash 0
|
|
return %0 : $(Builtin.Int64)
|
|
} // CHECK: Returns int: 25
|
|
|