Files
swift-mirror/test/SILOptimizer/constant_evaluator_test.sil
Ravi Kandhadai 9be4fef53a [SIL Optimization] Add a mandatory optimization pass for optimizing
the new os log APIs based on string interpolation.
2019-05-14 18:08:59 -07:00

1079 lines
44 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: @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 trucated 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: 512 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: cannot evaluate expression as constant here
%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 a function 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.1, %2 : $Int64
switch_enum %3 : $Shape, case #Shape.square!enumelt.1: bb1, case #Shape.rectangle!enumelt.1: 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: @interpretEscapeMutiplePercent
sil @interpretEscapeMutiplePercent : $@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%%"