mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
284 lines
9.4 KiB
Plaintext
284 lines
9.4 KiB
Plaintext
// RUN: %target-sil-opt -loop-rotate -update-borrowed-from -looprotate-single-block-loop=true -looprotate-infinite-budget %s | %FileCheck %s
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class Klass {
|
|
}
|
|
|
|
struct BoxStruct {
|
|
var guts: Klass
|
|
}
|
|
|
|
sil [ossa] @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
|
|
sil [ossa] @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
|
|
sil [ossa] @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopSimple :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopSimple'
|
|
sil [ossa] @testLoopSimple : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%c1 = apply %f1(%4) : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %c1: $Klass)
|
|
|
|
bb3:
|
|
destroy_value %c1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopCopy :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopCopy'
|
|
sil [ossa] @testLoopCopy : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @klassIdentity : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%copy = copy_value %4 : $Klass
|
|
destroy_value %4 : $Klass
|
|
%c1 = apply %f1(%copy) : $@convention(thin) (@owned Klass) -> @owned Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %c1: $Klass)
|
|
|
|
bb3:
|
|
destroy_value %c1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow1 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow1'
|
|
sil [ossa] @testLoopBorrow1 : $@convention(thin) (Int32, @owned Klass) -> (){
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
br bb1(%2 : $Builtin.Int32, %1 : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %4: @owned $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%borrow = begin_borrow %4 : $Klass
|
|
%c1 = apply %f1(%borrow) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
end_borrow %borrow : $Klass
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %4 : $Klass)
|
|
|
|
bb3:
|
|
destroy_value %4 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow2 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow2'
|
|
sil [ossa] @testLoopBorrow2 : $@convention(thin) (Int32, @owned Klass) -> () {
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
%borrow = begin_borrow %1 : $Klass
|
|
br bb1(%2 : $Builtin.Int32, %borrow : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %reborrow : @guaranteed $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%c1 = apply %f1(%reborrow) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %reborrow : $Klass)
|
|
|
|
bb3:
|
|
end_borrow %reborrow : $Klass
|
|
destroy_value %1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testLoopBorrow3 :
|
|
// CHECK: bb0(%0 : $Int32, %1 : @owned $Klass):
|
|
// CHECK: cond_br {{.*}}, bb2, bb1
|
|
// CHECK: bb1:
|
|
// CHECK-LABEL: } // end sil function 'testLoopBorrow3'
|
|
sil [ossa] @testLoopBorrow3 : $@convention(thin) (Int32, @owned Klass) -> () {
|
|
bb0(%0 : $Int32, %1: @owned $Klass):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value
|
|
%one = integer_literal $Builtin.Int32, 1
|
|
%borrow = begin_borrow %1 : $Klass
|
|
br bb1(%2 : $Builtin.Int32, %borrow : $Klass)
|
|
|
|
bb1(%3 : $Builtin.Int32, %reborrow1 : @guaranteed $Klass):
|
|
%f1 = function_ref @useKlass : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%c1 = apply %f1(%reborrow1) : $@convention(thin) (@guaranteed Klass) -> ()
|
|
%f2 = function_ref @increment : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%c2 = apply %f2(%3) : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
|
|
%5 = struct $Int32 (%c2 : $Builtin.Int32)
|
|
%6 = builtin "cmp_eq_Word"(%5 : $Int32, %one : $Builtin.Int32) : $Builtin.Int1
|
|
end_borrow %reborrow1 : $Klass
|
|
%reborrow2 = begin_borrow %1 : $Klass
|
|
cond_br %6, bb3, bb2
|
|
|
|
bb2:
|
|
br bb1(%c2 : $Builtin.Int32, %reborrow2 : $Klass)
|
|
|
|
bb3:
|
|
end_borrow %reborrow2 : $Klass
|
|
destroy_value %1 : $Klass
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @guaranteed_phi_argument : $@convention(thin) (@owned Klass) -> () {
|
|
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @reborrow $Klass):
|
|
// CHECK-LABEL: } // end sil function 'guaranteed_phi_argument'
|
|
sil [ossa] @guaranteed_phi_argument : $@convention(thin) (@owned Klass) -> () {
|
|
entry(%instance : @owned $Klass):
|
|
%lifetime_1 = begin_borrow [lexical] %instance : $Klass
|
|
br loop_header(%lifetime_1 : $Klass)
|
|
|
|
loop_header(%lifetime_2 : @guaranteed $Klass):
|
|
cond_br undef, loop_back_1, loop_back_2_or_exit
|
|
|
|
loop_back_1:
|
|
br loop_header(%lifetime_2 : $Klass)
|
|
|
|
loop_back_2_or_exit:
|
|
cond_br undef, loop_back_2, exit
|
|
|
|
loop_back_2:
|
|
br loop_header(%lifetime_2 : $Klass)
|
|
|
|
exit:
|
|
end_borrow %lifetime_2 : $Klass
|
|
destroy_value %instance : $Klass
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|
|
// A guaranteed value whose ownership has been forwarded must not be reborrowed.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @forwarded_borrow_cant_be_reborrowed : $@convention(thin) (@owned BoxStruct) -> () {
|
|
// CHECK-LABEL: } // end sil function 'forwarded_borrow_cant_be_reborrowed'
|
|
sil [ossa] @forwarded_borrow_cant_be_reborrowed : $@convention(thin) (@owned BoxStruct) -> () {
|
|
bb0(%0 : @owned $BoxStruct):
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = integer_literal $Builtin.Int1, 0
|
|
cond_br %2, bb2, bb3
|
|
|
|
bb2:
|
|
br bb9
|
|
|
|
bb3:
|
|
%5 = begin_borrow %0 : $BoxStruct
|
|
%6 = struct_extract %5 : $BoxStruct, #BoxStruct.guts
|
|
%7 = integer_literal $Builtin.Int1, 0
|
|
br bb4
|
|
|
|
bb4:
|
|
%10 = begin_borrow %6 : $Klass
|
|
end_borrow %10 : $Klass
|
|
end_borrow %5 : $BoxStruct
|
|
br bb5
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
|
|
bb6:
|
|
%16 = integer_literal $Builtin.Int1, -1
|
|
cond_br %16, bb7, bb8
|
|
|
|
bb7:
|
|
br bb9
|
|
|
|
bb8:
|
|
br bb1
|
|
|
|
bb9:
|
|
unreachable
|
|
}
|
|
|
|
// Ensure no verifier error
|
|
|
|
sil @foo : $@convention(thin) (@in_guaranteed UInt64, @in_guaranteed UInt64) -> (Bool, @error any Error)
|
|
|
|
sil [ossa] @looprotate_ownership_results : $@convention(thin) (Int32, @guaranteed Klass) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : @guaranteed $Klass):
|
|
%2 = struct_extract %0, #Int32._value
|
|
%3 = integer_literal $Builtin.Int32, 0
|
|
br bb1(%2, %3)
|
|
|
|
bb1(%5 : $Builtin.Int32, %6 : $Builtin.Int32):
|
|
%7 = function_ref @foo : $@convention(thin) (@in_guaranteed UInt64, @in_guaranteed UInt64) -> (Bool, @error any Error)
|
|
%8 = thin_to_thick_function %7 to $@noescape @callee_guaranteed (@in_guaranteed UInt64, @in_guaranteed UInt64) -> (Bool, @error any Error)
|
|
%9 = convert_function %8 to $@noescape @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (Bool, @error any Error) for <UInt64, UInt64>, forwarding: @owned
|
|
destroy_value %9
|
|
%11 = struct $Int32 (%6)
|
|
%12 = builtin "cmp_eq_Word"(%6, %2) : $Builtin.Int1
|
|
cond_br %12, bb3, bb2
|
|
|
|
bb2:
|
|
%14 = integer_literal $Builtin.Int32, 1
|
|
%15 = integer_literal $Builtin.Int1, -1
|
|
%16 = builtin "sadd_with_overflow_Word"(%6, %14, %15) : $(Builtin.Int32, Builtin.Int1)
|
|
%17 = tuple_extract %16, 0
|
|
%18 = enum $Optional<Int32>, #Optional.some!enumelt, %11
|
|
%19 = unchecked_enum_data %18, #Optional.some!enumelt
|
|
%20 = struct_extract %19, #Int32._value
|
|
%21 = integer_literal $Builtin.Int1, -1
|
|
%22 = builtin "sadd_with_overflow_Word"(%5, %20, %21) : $(Builtin.Int32, Builtin.Int1)
|
|
%23 = tuple_extract %22, 0
|
|
br bb1(%23, %17)
|
|
|
|
bb3:
|
|
%25 = struct $Int32 (%5)
|
|
return %25
|
|
}
|
|
|