Files
swift-mirror/test/SILOptimizer/enclosing_def_unit.sil
Erik Eckstein f363c3296e SIL: change the textual SIL output of a re-borrow phi from @reborrow @guaranteed to @reborrow
It's redundant because only guaranteed phis can be reborrows.
2024-11-13 10:39:14 +01:00

322 lines
12 KiB
Plaintext

// RUN: %target-sil-opt -update-borrowed-from -test-runner -sil-disable-input-verify %s -o /dev/null 2>&1 | %FileCheck %s
//
// REQUIRES: swift_in_compiler
sil_stage raw
import Builtin
struct Trivial {
var value: Builtin.Int32
}
enum FakeOptional<T> {
case none
case some(T)
}
struct PairC {
var first: C
var second: C
}
class C {
var field: C
}
class D : C {}
// These introducers have no enclosing def.
// CHECK-LABEL: enclosing_def_empty: find_enclosing_defs with: %0
// CHECK: } // end sil function 'enclosing_def_empty'
// CHECK: Enclosing Defs:
// CHECK-NEXT: enclosing_def_empty: find_enclosing_defs with: %0
// CHECK-LABEL: enclosing_def_empty: enclosing_values with: %0
// CHECK: } // end sil function 'enclosing_def_empty'
// CHECK: Enclosing values for: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_empty: enclosing_values with: %0
// CHECK-LABEL: enclosing_def_empty: find_enclosing_defs with: %borrow1
// CHECK: } // end sil function 'enclosing_def_empty'
// CHECK: Enclosing Defs:
// CHECK-NEXT: enclosing_def_empty: find_enclosing_defs with: %borrow1
// CHECK-LABEL: enclosing_def_empty: enclosing_values with: %borrow1
// CHECK: } // end sil function 'enclosing_def_empty'
// CHECK: Enclosing values for: %{{.*}} = load_borrow %1 : $*C
// CHECK-NEXT: enclosing_def_empty: enclosing_values with: %borrow1
sil [ossa] @enclosing_def_empty : $@convention(thin) (@guaranteed C, @in C) -> () {
entry(%0 : @guaranteed $C, %1 : $*C):
specify_test "find_enclosing_defs %0"
specify_test "enclosing_values %0"
%borrow1 = load_borrow %1 : $*C
specify_test "find_enclosing_defs %borrow1"
specify_test "enclosing_values %borrow1"
end_borrow %borrow1 : $C
destroy_addr %1 : $*C
%retval = tuple ()
return %retval : $()
}
// There is no introducer if the guaranteed value is produced from a
// trivial value.
// CHECK-LABEL: enclosing_def_trivial: find_enclosing_defs with: %phi
// CHECK: } // end sil function 'enclosing_def_trivial'
// CHECK: Enclosing Defs:
// CHECK-NEXT: enclosing_def_trivial: find_enclosing_defs with: %phi
// CHECK-LABEL: enclosing_def_trivial: enclosing_values with: %phi
// CHECK: } // end sil function 'enclosing_def_trivial'
// CHECK: Enclosing values for: %{{.*}} = argument of bb1 : $FakeOptional<C>
// CHECK-NEXT: enclosing_def_trivial: enclosing_values with: %phi
sil [ossa] @enclosing_def_trivial : $@convention(thin) () -> () {
entry:
%trivial = enum $FakeOptional<C>, #FakeOptional.none!enumelt
br none(%trivial : $FakeOptional<C>)
none(%phi : @guaranteed $FakeOptional<C>):
specify_test "find_enclosing_defs %phi"
specify_test "enclosing_values %phi"
%retval = tuple ()
return %retval : $()
}
// There is an introducer but no enclosing def if the guaranteed value
// is produced from a an unreachable loop.
// CHECK-LABEL: enclosing_def_unreachable: find_enclosing_defs with: %phiCycle
// CHECK: } // end sil function 'enclosing_def_unreachable'
// CHECK: Enclosing Defs:
// CHECK-NEXT: enclosing_def_unreachable: find_enclosing_defs with: %phiCycle
// CHECK-LABEL: enclosing_def_unreachable: enclosing_values with: %phiCycle
// CHECK: } // end sil function 'enclosing_def_unreachable'
// CHECK: Enclosing values for: %{{.*}} = argument of bb1 : $C
// CHECK-NEXT: enclosing_def_unreachable: enclosing_values with: %phiCycle
sil [ossa] @enclosing_def_unreachable : $@convention(thin) () ->() {
entry:
br exit
unreachable_loop(%phiCycle : @guaranteed $C):
specify_test "find_enclosing_defs %phiCycle"
specify_test "enclosing_values %phiCycle"
br unreachable_loop(%phiCycle : $C)
exit:
%retval = tuple ()
return %retval : $()
}
// All data flow paths through phis and aggregates originate from the
// same borrow scope. This is the same as finding the introducer.
// CHECK-LABEL: enclosing_def_single_introducer: find_enclosing_defs with: %aggregate2
// CHECK: sil [ossa] @enclosing_def_single_introducer
// CHECK: Enclosing Defs:
// CHECK: begin_borrow %0 : $C
// CHECK-NEXT: enclosing_def_single_introducer: find_enclosing_defs with: %aggregate2
// CHECK-LABEL: enclosing_def_single_introducer: enclosing_values with: %aggregate2
// CHECK: sil [ossa] @enclosing_def_single_introducer
// CHECK: Enclosing values for: %{{.*}} = struct $PairC (%11 : $C, %12 : $C)
// CHECK: begin_borrow %0 : $C
// CHECK-NEXT: enclosing_def_single_introducer: enclosing_values with: %aggregate2
sil [ossa] @enclosing_def_single_introducer : $@convention(thin) (@guaranteed C) -> () {
entry(%0 : @guaranteed $C):
%borrow = begin_borrow %0 : $C
%cast = unconditional_checked_cast %borrow : $C to D
%some = enum $FakeOptional<D>, #FakeOptional.some!enumelt, %cast : $D
br switch(%some : $FakeOptional<D>)
switch(%somePhi : @guaranteed $FakeOptional<D>):
switch_enum %somePhi : $FakeOptional<D>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
bb1(%payload : @guaranteed $D):
%upcast = upcast %payload : $D to $C
%aggregate = struct $PairC(%upcast : $C, %borrow : $C)
%first = struct_extract %aggregate : $PairC, #PairC.first
%second = struct_extract %aggregate : $PairC, #PairC.second
%aggregate2 = struct $PairC(%first : $C, %second : $C)
specify_test "find_enclosing_defs %aggregate2"
specify_test "enclosing_values %aggregate2"
br exit
bb2:
br exit
exit:
end_borrow %borrow : $C
%retval = tuple ()
return %retval : $()
}
// All reborrows original from the same dominating borrow scope.
// CHECK: enclosing_def_single_outer: find_enclosing_defs with: %reborrow3
// CHECK: } // end sil function 'enclosing_def_single_outer'
// CHECK: Enclosing Defs:
// CHECK-NEXT: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_single_outer: find_enclosing_defs with: %reborrow3
// CHECK: enclosing_def_single_outer: enclosing_values with: %reborrow3
// CHECK: } // end sil function 'enclosing_def_single_outer'
// CHECK: Enclosing values for: %{{.*}} = argument of bb2 : $C
// CHECK-NEXT: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_single_outer: enclosing_values with: %reborrow3
sil [ossa] @enclosing_def_single_outer : $@convention(thin) (@guaranteed C) -> () {
entry(%0 : @guaranteed $C):
%borrow = begin_borrow %0 : $C
br bb2(%borrow : $C)
bb2(%reborrow2 : @guaranteed $C):
br bb3(%reborrow2 : $C)
bb3(%reborrow3 : @guaranteed $C):
specify_test "find_enclosing_defs %reborrow3"
specify_test "enclosing_values %reborrow3"
end_borrow %reborrow3 : $C
%retval = tuple ()
return %retval : $()
}
// Find the outer enclosingreborrow.
// CHECK-LABEL: enclosing_def_reborrow: find_enclosing_defs with: %reborrow_inner3
// CHECK: sil [ossa] @enclosing_def_reborrow : $@convention(thin) (@guaranteed C) -> () {
// CHECK: bb1([[REBORROW:%.*]] : @reborrow $C, %{{.*}} : @reborrow $C):
// CHECK: } // end sil function 'enclosing_def_reborrow'
// CHECK: Enclosing Defs:
// CHECK-NEXT: [[REBORROW]] = argument of bb1 : $C
// CHECK-NEXT: enclosing_def_reborrow: find_enclosing_defs with: %reborrow_inner3
// CHECK-LABEL: enclosing_def_reborrow: enclosing_values with: %reborrow_inner3
// CHECK: sil [ossa] @enclosing_def_reborrow : $@convention(thin) (@guaranteed C) -> () {
// CHECK: bb1([[REBORROW:%.*]] : @reborrow $C, %{{.*}} : @reborrow $C):
// CHECK: } // end sil function 'enclosing_def_reborrow'
// CHECK: Enclosing values for: %{{.*}} = argument of bb2 : $C
// CHECK-NEXT: [[REBORROW]] = argument of bb1 : $C
// CHECK-NEXT: enclosing_def_reborrow: enclosing_values with: %reborrow_inner3
sil [ossa] @enclosing_def_reborrow : $@convention(thin) (@guaranteed C) -> () {
entry(%0 : @guaranteed $C):
%borrow_outer = begin_borrow %0 : $C
%borrow_inner = begin_borrow %borrow_outer : $C
br bb2(%borrow_outer : $C, %borrow_inner : $C)
bb2(%reborrow_outer : @guaranteed $C, %reborrow_inner : @guaranteed $C):
br bb3(%reborrow_inner : $C)
bb3(%reborrow_inner3 : @guaranteed $C):
specify_test "find_enclosing_defs %reborrow_inner3"
specify_test "enclosing_values %reborrow_inner3"
end_borrow %reborrow_inner3 : $C
end_borrow %reborrow_outer : $C
%retval = tuple ()
return %retval : $()
}
// The enclosing def of a forwarding phi cycle is the reborrow phi cycle.
// CHECK-LABEL: enclosing_def_cycle: find_enclosing_defs with: %forward
// CHECK: sil [ossa] @enclosing_def_cycle : $@convention(thin) (@guaranteed C) -> () {
// CHECK: bb1([[REBORROW:%.*]] : @guaranteed $C,
// CHECK: } // end sil function 'enclosing_def_cycle'
// CHECK: Enclosing Defs:
// CHECK-NEXT: [[REBORROW]] = argument of bb1 : $C
// CHECK-NEXT: enclosing_def_cycle: find_enclosing_defs with: %forward
// CHECK-LABEL: enclosing_def_cycle: enclosing_values with: %forward
// CHECK: sil [ossa] @enclosing_def_cycle : $@convention(thin) (@guaranteed C) -> () {
// CHECK: bb1([[REBORROW:%.*]] : @guaranteed $C,
// CHECK: } // end sil function 'enclosing_def_cycle'
// CHECK: Enclosing values for: %{{.*}} = argument of bb1 : $C
// CHECK-NEXT: %1 = begin_borrow %0
// CHECK-NEXT: %0 = argument of bb0
// CHECK-NEXT: enclosing_def_cycle: enclosing_values with: %forward
sil [ossa] @enclosing_def_cycle : $@convention(thin) (@guaranteed C) -> () {
entry(%0 : @guaranteed $C):
%borrow = begin_borrow %0 : $C
%aggregate1 = struct $PairC(%borrow : $C, %borrow : $C)
%first1 = struct_extract %aggregate1 : $PairC, #PairC.first
br bb2(%borrow : $C, %first1 : $C)
bb2(%reborrow_outer : @guaranteed $C, %forward : @guaranteed $C):
specify_test "find_enclosing_defs %forward"
specify_test "enclosing_values %forward"
%aggregate2 = struct $PairC(%reborrow_outer : $C, %forward : $C)
%first2 = struct_extract %aggregate2 : $PairC, #PairC.first
br bb2(%reborrow_outer : $C, %first2 : $C)
exit:
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: enclosing_def_example: enclosing_values with: %0
// CHECK: Enclosing values for: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_example: enclosing_values with: %0
// CHECK-LABEL: enclosing_def_example: enclosing_values with: %borrow0
// CHECK: Enclosing values for: %{{.*}} = begin_borrow %0 : $C
// CHECK-NEXT: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_example: enclosing_values with: %borrow0
// CHECK-LABEL: enclosing_def_example: enclosing_values with: %first
// CHECK: Enclosing values for: %{{.*}} = struct_extract %{{.*}} : $PairC, #PairC.first
// CHECK-NEXT: %{{.*}} = argument of bb0 : $C
// CHECK-NEXT: %{{.*}} = begin_borrow %0 : $C
// CHECK-NEXT: enclosing_def_example: enclosing_values with: %first
// CHECK-LABEL: enclosing_def_example: enclosing_values with: %field
// CHECK: Enclosing values for: %{{.*}} = ref_element_addr %{{.*}} : $C, #C.field
// CHECK-NEXT: enclosing_def_example: enclosing_values with: %field
// CHECK-LABEL: enclosing_def_example: enclosing_values with: %load
// CHECK: Enclosing values for: %{{.*}} = load_borrow %{{.*}} : $*C
// CHECK-NEXT: enclosing_def_example: enclosing_values with: %load
sil [ossa] @enclosing_def_example : $@convention(thin) (@owned C, @guaranteed C) -> () {
bb0(%0 : @owned $C,
%1 : @guaranteed $C):
specify_test "enclosing_values %0"
%borrow0 = begin_borrow %0 : $C
specify_test "enclosing_values %borrow0"
%pair = struct $PairC(%borrow0 : $C, %1 : $C)
%first = struct_extract %pair : $PairC, #PairC.first
specify_test "enclosing_values %first"
%field = ref_element_addr %first : $C, #C.field
specify_test "enclosing_values %field"
%load = load_borrow %field : $*C
specify_test "enclosing_values %load"
end_borrow %load : $C
end_borrow %borrow0 : $C
destroy_value %0 : $C
%retval = tuple ()
return %retval : $()
}
// CHECK-LABEL: enclosing_def_reborrow_example: enclosing_values with: %outerReborrow
// CHECK: Enclosing values for: %{{.*}} = argument of bb1 : $C
// CHECK-NEXT: %0 = argument of bb0 : $C
// CHECK-NEXT: enclosing_def_reborrow_example: enclosing_values with: %outerReborrow
// CHECK-LABEL: enclosing_def_reborrow_example: enclosing_values with: %innerReborrow
// CHECK: Enclosing values for: %{{.*}} = argument of bb1 : $C
// CHECK-NEXT: %{{.*}} = argument of bb1 : $C
// CHECK-NEXT: enclosing_def_reborrow_example: enclosing_values with: %innerReborrow
sil [ossa] @enclosing_def_reborrow_example : $@convention(thin) (@guaranteed C) -> () {
bb0(%0 : @guaranteed $C):
%outerBorrow = begin_borrow %0 : $C
%innerBorrow = begin_borrow %outerBorrow : $C
br bb1(%outerBorrow : $C, %innerBorrow : $C)
bb1(%outerReborrow : @guaranteed $C, %innerReborrow : @guaranteed $C):
specify_test "enclosing_values %outerReborrow"
specify_test "enclosing_values %innerReborrow"
end_borrow %innerReborrow : $C
end_borrow %outerReborrow : $C
%retval = tuple ()
return %retval : $()
}