mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
169 lines
5.1 KiB
Swift
169 lines
5.1 KiB
Swift
// RUN: %target-swift-frontend -primary-file %s -O -sil-verify-all -module-name=test -Xllvm -sil-print-types -emit-sil | %FileCheck %s
|
|
|
|
// Also do an end-to-end test to check if the generated code is correct.
|
|
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift -O -module-name=test %s -o %t/a.out
|
|
// RUN: %target-codesign %t/a.out
|
|
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
|
|
// REQUIRES: executable_test
|
|
|
|
var g = 0
|
|
|
|
final class Myclass {
|
|
lazy var lvar: Int = {
|
|
print("lvar init")
|
|
return g
|
|
}()
|
|
}
|
|
|
|
struct Mystruct {
|
|
lazy var lvar: Int = {
|
|
print("lvar init")
|
|
return g
|
|
}()
|
|
}
|
|
|
|
// CHECK-LABEL: sil {{.*}} @$s4test0A7_simpleySiAA7MyclassCF
|
|
// CHECK: [[GETTER:%[0-9]+]] = function_ref @$s4test7MyclassC4lvarSivg
|
|
// CHECK: [[V1:%[0-9]+]] = apply [[GETTER]](%0)
|
|
// CHECK: [[V2OPT:%[0-9]+]] = load
|
|
// CHECK: [[V2:%[0-9]+]] = unchecked_enum_data [[V2OPT]]
|
|
// CHECK: [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
|
|
// CHECK: [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
|
|
// CHECK: builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
|
|
// CHECK: } // end sil function '$s4test0A7_simpleySiAA7MyclassCF'
|
|
@inline(never)
|
|
func test_simple(_ c: Myclass) -> Int {
|
|
g = 27
|
|
let v1 = c.lvar
|
|
let v2 = c.lvar
|
|
return v1 &+ v2
|
|
}
|
|
|
|
// CHECK-LABEL: sil {{.*}} @$s4test0A4_cfgySiAA7MyclassC_SbtF
|
|
// CHECK: [[GETTER:%[0-9]+]] = function_ref @$s4test7MyclassC4lvarSivg
|
|
// CHECK: [[V1:%[0-9]+]] = apply [[GETTER]](%0)
|
|
// CHECK: bb1:
|
|
// CHECK: [[V2OPT:%[0-9]+]] = load
|
|
// CHECK: [[V2:%[0-9]+]] = unchecked_enum_data [[V2OPT]]
|
|
// CHECK: [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
|
|
// CHECK: br bb3([[V2VAL]]
|
|
// CHECK: bb2:
|
|
// CHECK: bb3([[V2PHI:%[0-9]+]] {{.*}}):
|
|
// CHECK: [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
|
|
// CHECK: builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2PHI]]
|
|
// CHECK: } // end sil function '$s4test0A4_cfgySiAA7MyclassC_SbtF'
|
|
@inline(never)
|
|
func test_cfg(_ c: Myclass, _ b: Bool) -> Int {
|
|
g = 10
|
|
let v1 = c.lvar
|
|
var v2: Int
|
|
if b {
|
|
v2 = c.lvar
|
|
} else {
|
|
v2 = 0
|
|
}
|
|
return v1 &+ v2
|
|
}
|
|
|
|
// CHECK-LABEL: sil {{.*}} @$s4test0A12_no_hoistingySiAA7MyclassC_SbtF
|
|
// CHECK: bb1:
|
|
// CHECK: [[GETTER1:%[0-9]+]] = function_ref @$s4test7MyclassC4lvarSivg
|
|
// CHECK: = apply [[GETTER1]](%0)
|
|
// CHECK: bb2:
|
|
// CHECK: [[GETTER2:%[0-9]+]] = function_ref @$s4test7MyclassC4lvarSivg
|
|
// CHECK: = apply [[GETTER2]](%0)
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: } // end sil function '$s4test0A12_no_hoistingySiAA7MyclassC_SbtF'
|
|
@inline(never)
|
|
func test_no_hoisting(_ c: Myclass, _ b: Bool) -> Int {
|
|
var v: Int
|
|
if b {
|
|
g = 20
|
|
v = c.lvar + 2
|
|
} else {
|
|
g = 30
|
|
v = c.lvar + 3
|
|
}
|
|
return v
|
|
}
|
|
|
|
// This test is disabled, because for structs, it does not work yet.
|
|
// CSE is too conservative to handle indirect getter arguments currently.
|
|
|
|
// CHECK-LABEL: sil {{.*}} @$s4test0A7_structySiAA8MystructVF
|
|
// CHECK-DISABLED: [[GETTER:%[0-9]+]] = function_ref @$s4test8MystructV4lvarSivg
|
|
// CHECK-DISABLED: [[V1:%[0-9]+]] = apply [[GETTER]]({{.*}})
|
|
// CHECK-DISABLED: [[V2OPT:%[0-9]+]] = load
|
|
// CHECK-DISABLED: [[V2:%[0-9]+]] = unchecked_enum_data [[V2OPT]]
|
|
// CHECK-DISABLED: [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
|
|
// CHECK-DISABLED: [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
|
|
// CHECK-DISABLED: builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
|
|
// CHECK-DISABLED: } // end sil function '$s4test0A7_structySiAA8MystructVF'
|
|
@inline(never)
|
|
func test_struct(_ s: Mystruct) -> Int {
|
|
var sm = s
|
|
g = 42
|
|
let v1 = sm.lvar
|
|
let v2 = sm.lvar
|
|
return v1 &+ v2
|
|
}
|
|
|
|
// CHECK-LABEL: sil {{.*}} @$s4test0A19_overwritten_structySiAA8MystructVF
|
|
// CHECK: [[GETTER:%[0-9]+]] = function_ref @$s4test8MystructV4lvarSivg
|
|
// CHECK: [[V1:%[0-9]+]] = apply [[GETTER]]({{.*}})
|
|
// CHECK: [[V2:%[0-9]+]] = apply [[GETTER]]({{.*}})
|
|
// CHECK: [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
|
|
// CHECK: [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
|
|
// CHECK: builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
|
|
// CHECK: } // end sil function '$s4test0A19_overwritten_structySiAA8MystructVF'
|
|
@inline(never)
|
|
func test_overwritten_struct(_ s: Mystruct) -> Int {
|
|
var sm = s
|
|
g = 42
|
|
let v1 = sm.lvar
|
|
sm = s
|
|
g = 43
|
|
let v2 = sm.lvar
|
|
return v1 &+ v2
|
|
}
|
|
|
|
func calltests() {
|
|
// CHECK-OUTPUT-LABEL: test_simple
|
|
print("test_simple")
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 54
|
|
print(test_simple(Myclass()))
|
|
|
|
// CHECK-OUTPUT-LABEL: test_cfg
|
|
print("test_cfg")
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 20
|
|
print(test_cfg(Myclass(), true))
|
|
|
|
// CHECK-OUTPUT-LABEL: test_no_hoisting
|
|
print("test_no_hoisting")
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 22
|
|
print(test_no_hoisting(Myclass(), true))
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 33
|
|
print(test_no_hoisting(Myclass(), false))
|
|
|
|
// CHECK-OUTPUT-LABEL: test_struct
|
|
print("test_struct")
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 84
|
|
print(test_struct(Mystruct()))
|
|
|
|
// CHECK-OUTPUT-LABEL: test_overwritten_struct
|
|
print("test_overwritten_struct")
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: lvar init
|
|
// CHECK-OUTPUT-NEXT: 85
|
|
print(test_overwritten_struct(Mystruct()))
|
|
}
|
|
|
|
calltests()
|
|
|