Files
swift-mirror/test/SILOptimizer/simplify_release_value.sil
Erik Eckstein 7cceaff5f3 SIL: don't print operand types in textual SIL
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.
2024-11-21 18:49:52 +01:00

209 lines
6.6 KiB
Plaintext

// RUN: %target-sil-opt -sil-print-types -enable-experimental-feature MoveOnlyEnumDeinits -enable-sil-verify-all %s -simplification -simplify-instruction=release_value | %FileCheck %s
// REQUIRES: swift_in_compiler
// REQUIRES: swift_feature_MoveOnlyEnumDeinits
import Swift
import Builtin
class C {}
enum U {
init()
case X
case Y(Builtin.Int64)
case Z(C)
}
enum EnumWithPayload {
case A(UInt64)
case B(AnyObject)
case C
}
struct WithDeinit : ~Copyable {
deinit
}
struct Outer : ~Copyable {
var wd: WithDeinit
}
enum EnumWithDeinit: ~Copyable {
case A(Int64)
case B
deinit
}
struct TwoEnums {
var u1: U
var u2: U
}
struct MyStringObj {
@_hasStorage var a: UInt64
@_hasStorage var b: Builtin.BridgeObject
}
struct MyStringGuts {
@_hasStorage var o: MyStringObj
}
struct MyString {
@_hasStorage var g: MyStringGuts
}
// CHECK-LABEL: sil @release_value_test
// CHECK: bb0({{%[0-9]+}} : $Builtin.Int8, [[RELEASE_TARGET:%[0-9]+]] : $Builtin.NativeObject):
// CHECK-NEXT: strong_release [[RELEASE_TARGET]] : $Builtin.NativeObject
// CHECK-NEXT: tuple ()
// CHECK-NEXT: return
// CHECK: } // end sil function 'release_value_test'
sil @release_value_test : $@convention(thin) (Builtin.Int8, Builtin.NativeObject) -> () {
bb0(%0 : $Builtin.Int8, %1 : $Builtin.NativeObject):
release_value %0 : $Builtin.Int8
release_value %1 : $Builtin.NativeObject
%2 = tuple()
return %2 : $()
}
// CHECK-LABEL: sil @dont_remove_struct_with_deinit_field
// CHECK: release_value %0
// CHECK: } // end sil function 'dont_remove_struct_with_deinit_field'
sil @dont_remove_struct_with_deinit_field : $@convention(thin) (Outer) -> () {
bb0(%0 : $Outer):
release_value %0 : $Outer
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil @struct_with_two_trivial_enums
// CHECK-NOT: release_value
// CHECK: } // end sil function 'struct_with_two_trivial_enums'
sil @struct_with_two_trivial_enums : $@convention(thin) (Builtin.Int64) -> () {
bb0(%0 : $Builtin.Int64):
%1 = enum $U, #U.X!enumelt
%2 = enum $U, #U.Y!enumelt, %0 : $Builtin.Int64
%3 = struct $TwoEnums (%1 : $U, %2 : $U)
release_value %3 : $TwoEnums
%5 = tuple ()
return %5 : $()
}
// CHECK-LABEL: sil @struct_with_non_trivial_enums
// CHECK: release_value
// CHECK: } // end sil function 'struct_with_non_trivial_enums'
sil @struct_with_non_trivial_enums : $@convention(thin) (@guaranteed C) -> () {
bb0(%0 : $C):
%1 = enum $U, #U.X!enumelt
%2 = enum $U, #U.Z!enumelt, %0 : $C
%3 = struct $TwoEnums (%1 : $U, %2 : $U)
release_value %3 : $TwoEnums
%5 = tuple ()
return %5 : $()
}
// CHECK-LABEL: sil @remove_value_to_bridge_object
// CHECK: bb0(%0 : $UInt64):
// CHECK-NEXT: tuple
// CHECK-NEXT: return
// CHECK: } // end sil function 'remove_value_to_bridge_object'
sil @remove_value_to_bridge_object : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = integer_literal $Builtin.Int64, -1945555039024054272
%2 = value_to_bridge_object %1 : $Builtin.Int64
%3 = struct $MyStringObj (%0 : $UInt64, %2 : $Builtin.BridgeObject)
%4 = struct $MyStringGuts (%3 : $MyStringObj)
%5 = struct $MyString (%4 : $MyStringGuts)
release_value %5 : $MyString
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil @sil_destroyvalue_of_enum
// CHECK: bb0([[TYPE_ARG:%[0-9]+]] : $@thin U.Type, [[CLASS_ARG:%[0-9]+]] : $C):
// CHECK-NEXT: enum $U, #U.X!enumelt
// CHECK-NEXT: integer_literal $Builtin.Int64, 32
// CHECK-NEXT: enum $U, #U.Y!enumelt, {{%[0-9]+}} : $Builtin.Int64
// CHECK-NEXT: [[INVALID_CASE:%[0-9]+]] = enum $U, #U.Z!enumelt, {{%[0-9]+}} : $C
// CHECK-NEXT: strong_release [[CLASS_ARG]] : $C
// CHECK-NEXT: tuple ({{%[0-9]+}} : $U, {{%[0-9]+}} : $U, [[INVALID_CASE]] : $U)
// CHECK-NEXT: return
// CHECK: } // end sil function 'sil_destroyvalue_of_enum'
sil @sil_destroyvalue_of_enum : $@convention(thin) (@thin U.Type, C) -> (U, U, U) {
bb0(%0 : $@thin U.Type, %1 : $C):
%2 = enum $U, #U.X!enumelt
release_value %2 : $U
%3 = integer_literal $Builtin.Int64, 32
%4 = enum $U, #U.Y!enumelt, %3 : $Builtin.Int64
release_value %4 : $U
%5 = enum $U, #U.Z!enumelt, %1 : $C
release_value %5 : $U
%6 = tuple(%2 : $U, %4 : $U, %5 : $U)
return %6 : $(U, U, U)
}
// CHECK-LABEL: sil @ref_ops_of_enum_is_equivalent_to_ref_ops_of_payload :
// CHECK: bb0
// CHECK-NEXT: enum
// CHECK-NEXT: strong_release %0
// CHECK-NEXT: return
// CHECK: } // end sil function 'ref_ops_of_enum_is_equivalent_to_ref_ops_of_payload'
sil @ref_ops_of_enum_is_equivalent_to_ref_ops_of_payload : $@convention(thin) (Builtin.NativeObject) -> Optional<Builtin.NativeObject> {
bb0(%0 : $Builtin.NativeObject):
%1 = enum $Optional<Builtin.NativeObject>, #Optional.some!enumelt, %0 : $Builtin.NativeObject
release_value %1 : $Optional<Builtin.NativeObject>
return %1 : $Optional<Builtin.NativeObject>
}
// CHECK-LABEL: sil @lower_retainrelease_value_of_unowned_to_unowned_retainrelease :
// CHECK: unowned_release
// CHECK: } // end sil function 'lower_retainrelease_value_of_unowned_to_unowned_retainrelease'
sil @lower_retainrelease_value_of_unowned_to_unowned_retainrelease : $@convention(thin) (@owned @sil_unowned C) -> () {
bb0(%0 : $@sil_unowned C):
release_value %0 : $@sil_unowned C
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @optimize_arc_with_trivial_payload_enum
// CHECK: bb0(%0 : $UInt64):
// CHECK-NEXT: tuple
// CHECK-NEXT: return
// CHECK: } // end sil function 'optimize_arc_with_trivial_payload_enum'
sil @optimize_arc_with_trivial_payload_enum : $@convention(thin) (UInt64) -> () {
bb0(%0 : $UInt64):
%1 = enum $EnumWithPayload, #EnumWithPayload.A!enumelt, %0 : $UInt64
release_value %1 : $EnumWithPayload
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil @optimize_arc_with_trivial_enum
// CHECK: bb0:
// CHECK-NEXT: tuple
// CHECK-NEXT: return
// CHECK: } // end sil function 'optimize_arc_with_trivial_enum'
sil @optimize_arc_with_trivial_enum : $@convention(thin) () -> () {
bb0:
%1 = enum $EnumWithPayload, #EnumWithPayload.C!enumelt
release_value %1 : $EnumWithPayload
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil @dont_remove_release_of_nontrivial_enum
// CHECK: strong_release %0
// CHECK: } // end sil function 'dont_remove_release_of_nontrivial_enum'
sil @dont_remove_release_of_nontrivial_enum : $@convention(thin) (@guaranteed AnyObject) -> () {
bb0(%0 : $AnyObject):
%1 = enum $EnumWithPayload, #EnumWithPayload.B!enumelt, %0 : $AnyObject
release_value %1 : $EnumWithPayload
%7 = tuple ()
return %7 : $()
}