Files
swift-mirror/test/SILOptimizer/looprotate_nontrivial_ossa.sil
2025-02-18 14:42:28 -08:00

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
}