blob: b2af14e39920ba0af8122e56aae9b922988994c3 [file] [log] [blame]
// RUN: %target-swift-frontend -primary-file %s -emit-sil -o - -verify | FileCheck %s
// These tests are deliberately shallow, because I do not want to depend on the
// specifics of SIL generation, which might change for reasons unrelated to this
// pass
func foo(x: Float) -> Float {
return bar(x);
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining3foo
// CHECK: bb0(%0 : $Float):
// CHECK-NEXT: debug_value %0 : $Float, let, name "x"
// CHECK-NEXT: return %0
@_transparent func bar(x: Float) -> Float {
return baz(x)
}
// CHECK-LABEL: sil hidden [transparent] @_TF18mandatory_inlining3bar
// CHECK-NOT: function_ref
// CHECK-NOT: apply
// CHECK: return
@_transparent func baz(x: Float) -> Float {
return x;
}
// CHECK-LABEL: sil hidden [transparent] @_TF18mandatory_inlining3baz
// CHECK: return
func spam(x: Int) -> Int {
return x
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining4spam
@_transparent func ham(x: Int) -> Int {
return spam(x)
}
// CHECK-LABEL: sil hidden [transparent] @_TF18mandatory_inlining3ham
// CHECK: function_ref @_TF18mandatory_inlining4spam
// CHECK: apply
// CHECK: return
func eggs(x: Int) -> Int {
return ham(x)
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining4eggs
// CHECK: function_ref @_TF18mandatory_inlining4spam
// CHECK: apply
// CHECK: return
@_transparent func call_auto_closure(@autoclosure x: () -> Bool) -> Bool {
return x()
}
func test_auto_closure_with_capture(x: Bool) -> Bool {
return call_auto_closure(x)
}
// This should be fully inlined and simply return x; however, there's a lot of
// non-SSA cruft that I don't want this test to depend on, so I'm just going
// to verify that it doesn't have any function applications left
// CHECK-LABEL: sil hidden @{{.*}}test_auto_closure_with_capture
// CHECK-NOT: = apply
// CHECK: return
func test_auto_closure_without_capture() -> Bool {
return call_auto_closure(false)
}
// This should be fully inlined and simply return false, which is easier to check for
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining33test_auto_closure_without_captureFT_Sb
// CHECK: [[FV:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK: [[FALSE:%.*]] = struct $Bool ([[FV:%.*]] : $Builtin.Int1)
// CHECK: return [[FALSE]]
@_transparent func test_curried(x: Int)(y: Int) -> Int { // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}}
return y
}
func call_uncurried(x: Int, y: Int) -> Int {
return test_curried(x)(y: y)
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining14call_uncurried
// CHECK-NOT: = apply
// CHECK: return
func call_curried(x: Int, y: Int) -> Int {
let z = test_curried(x)
return z(y: y)
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining12call_curried
// CHECK: = apply
// CHECK: = apply
// CHECK: return
infix operator &&& {
associativity left
precedence 120
}
infix operator ||| {
associativity left
precedence 110
}
@_transparent func &&& (lhs: Bool, @autoclosure rhs: ()->Bool) -> Bool {
if lhs {
return rhs()
}
return false
}
@_transparent func ||| (lhs: Bool, @autoclosure rhs: ()->Bool) -> Bool {
if lhs {
return true
}
return rhs()
}
func test_chained_short_circuit(x: Bool, y: Bool, z: Bool) -> Bool {
return x &&& (y ||| z)
}
// The test below just makes sure there are no uninlined [transparent] calls
// left (i.e. the autoclosure and the short-circuiting boolean operators are
// recursively inlined properly)
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining26test_chained_short_circuit
// CHECK-NOT = apply [transparent]
// CHECK: return
// Union element constructors should be inlined automatically.
enum X {
case onetransp
case twotransp
}
func testInlineUnionElement() -> X {
return X.onetransp;
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining22testInlineUnionElementFT_OS_1X
// CHECK: enum $X, #X.onetransp!enumelt
// CHECK-NOT = apply
// CHECK: return
}
@_transparent
func call_let_auto_closure(@autoclosure x: () -> Bool) -> Bool {
return x()
}
// CHECK: sil hidden @{{.*}}test_let_auto_closure_with_value_capture
// CHECK: bb0(%0 : $Bool):
// CHECK-NEXT: debug_value %0 : $Bool
// CHECK-NEXT: return %0 : $Bool
func test_let_auto_closure_with_value_capture(x: Bool) -> Bool {
return call_let_auto_closure(x)
}
class C {}
// CHECK-LABEL: sil hidden [transparent] @_TF18mandatory_inlining25class_constrained_generic
@_transparent
func class_constrained_generic<T : C>(o: T) -> AnyClass? {
// CHECK: return
return T.self
}
// CHECK-LABEL: sil hidden @_TF18mandatory_inlining6invokeFCS_1CT_ : $@convention(thin) (@owned C) -> () {
func invoke(c: C) {
// CHECK-NOT: function_ref @_TF18mandatory_inlining25class_constrained_generic
// CHECK-NOT: apply
// CHECK: init_existential_metatype
class_constrained_generic(c)
// CHECK: return
}