Files
swift-mirror/validation-test/SILOptimizer/rdar113142446.sil
Nate Chandler cae89a9562 [ConsumeObjectChecker] End lifetimes at consumes.
The checker already verifies that no non-destroy consuming users occur
after any `move_value`s corresponding to `consume` operators applied to
a value.  There may, however, be _destroy_ users after it.

Previously, the checker did not shorten the lifetime from those destroys
up to `move_value`s that appear after those `move_value`s.  The result
was that the value's lifetime didn't end at the `consume`.

Here, the checker is fixed to rewrite the lifetimes so that they both
end at `consume`s and also maintain their lexical lifetimes on paths
away from the `consume`s.  This is done by using
`OwnedValueCanonicalization`/`CanonicalizeOSSALifetime`.

Specifically, it passes the `move_value`s that correspond to
source-level `consume`s as the `lexicalLifetimeEnds` to the
canonicalizer.  Typically, the canonicalizer retracts the lexical
lifetime of the value from its destroys.  When these `move_value`s are
specified, however, instead it retracts them from the lifetime boundary
obtained by maximizing the lifetime within its original lifetime while
maintaining the property that the lifetime ends at those `move_value`s.

rdar://113142446
2024-06-03 15:45:32 -07:00

32 lines
1.1 KiB
Plaintext

// RUN: %target-sil-opt -opt-mode=none -enable-sil-verify-all %s -sil-consume-operator-copyable-values-checker | %FileCheck %s
// RUN: %target-sil-opt -opt-mode=speed -enable-sil-verify-all %s -sil-consume-operator-copyable-values-checker | %FileCheck %s
sil_stage raw
import Builtin
class X {}
struct S {}
sil @getX : $@convention(thin) () -> @owned X
sil @takeX : $@convention(thin) (@owned X) -> S
// CHECK-LABEL: sil [ossa] @testit : {{.*}} {
// CHECK-NOT: copy_value
// CHECK-LABEL: } // end sil function 'testit'
sil [ossa] @testit : $@convention(thin) () -> () {
%getX = function_ref @getX : $@convention(thin) () -> @owned X
%x = apply %getX() : $@convention(thin) () -> @owned X
%begin = move_value [lexical] [var_decl] %x : $X
debug_value %begin : $X, let, name "x"
%copy = copy_value %begin : $X
%consume = move_value [allows_diagnostics] %copy : $X
%takeX = function_ref @takeX : $@convention(thin) (@owned X) -> S
apply %takeX(%consume) : $@convention(thin) (@owned X) -> S
destroy_value %begin : $X
%retval = tuple ()
return %retval : $()
}