Files
swift-mirror/test/SILOptimizer/simplify_cfg_ossa_jump_threading.sil
Nate Chandler 8d3a5a17d9 [Test] Underscored simplify_cfg_try_jump_threading.
Use underscores rather than hyphens so that text editors understand the
name as a single word.
2024-07-25 13:47:45 -07:00

321 lines
11 KiB
Plaintext

// RUN: %target-sil-opt -test-runner -sil-infinite-jump-threading-budget %s 2>&1 | %FileCheck %s
import Builtin
import Swift
class Klass {
var val: Int
}
class AnyKlass { }
enum FakeOptional<T> {
case some(T)
case none
}
sil @get_klass : $@convention(thin) () -> @owned Klass
// This test is not optimized because the dest bb of the branch has a single predecessor
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum_jump_threading1 :
// CHECK: switch_enum
// CHECK-NOT: switch_enum
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum_jump_threading1'
sil [ossa] @test_simplify_switch_enum_jump_threading1 : $@convention(thin) (@owned Klass) -> () {
bb0(%0 : @owned $Klass):
specify_test "simplify_cfg_try_jump_threading @instruction[1]"
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
br bb1(%1 : $FakeOptional<Klass>)
bb1(%3 : @owned $FakeOptional<Klass>):
switch_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb3, case #FakeOptional.none!enumelt: bb2
bb2:
br bb4
bb3(%6 : @owned $Klass):
destroy_value %6 : $Klass
br bb4
bb4:
%t = tuple ()
return %t : $()
}
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum_jump_threading2 :
// CHECK: switch_enum
// CHECK: switch_enum
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum_jump_threading2'
sil [ossa] @test_simplify_switch_enum_jump_threading2 : $@convention(thin) (@owned Klass) -> () {
bb0(%0 : @owned $Klass):
cond_br undef, bb1, bb2
bb1:
specify_test "simplify_cfg_try_jump_threading @instruction[2]"
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
br bb3(%1 : $FakeOptional<Klass>)
bb2:
specify_test "simplify_cfg_try_jump_threading @instruction[5]"
destroy_value %0 : $Klass
%2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
br bb3(%2 : $FakeOptional<Klass>)
bb3(%3 : @owned $FakeOptional<Klass>):
switch_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb5, case #FakeOptional.none!enumelt: bb4
bb4:
br bb6
bb5(%6 : @owned $Klass):
destroy_value %6 : $Klass
br bb6
bb6:
%t = tuple ()
return %t : $()
}
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum_jump_threading3 :
// CHECK: select_enum
// CHECK: select_enum
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum_jump_threading3'
sil [ossa] @test_simplify_switch_enum_jump_threading3 : $@convention(thin) (@owned Klass) -> Builtin.Int1 {
bb0(%0 : @owned $Klass):
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
cond_br undef, bb1, bb2
bb1:
specify_test "simplify_cfg_try_jump_threading @instruction[4]"
%1 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
br bb3(%1 : $FakeOptional<Klass>)
bb2:
destroy_value %0 : $Klass
%2 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
br bb3(%2 : $FakeOptional<Klass>)
bb3(%3 : @owned $FakeOptional<Klass>):
%4 = select_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: %t, case #FakeOptional.none!enumelt: %f : $Builtin.Int1
destroy_value %3 : $FakeOptional<Klass>
br bb4
bb4:
return %4 : $Builtin.Int1
}
// CHECK-LABEL: sil [ossa] @test_jump_thread_ref_ele_loop : $@convention(thin) () -> () {
// CHECK: begin_borrow
// CHECK: begin_borrow
// CHECK-LABEL: } // end sil function 'test_jump_thread_ref_ele_loop'
sil [ossa] @test_jump_thread_ref_ele_loop : $@convention(thin) () -> () {
bb0:
specify_test "simplify_cfg_try_jump_threading @instruction[3]"
%f = function_ref @get_klass : $@convention(thin) () -> @owned Klass
cond_br undef, bb1, bb2
bb1:
%c1 = apply %f() : $@convention(thin) () -> @owned Klass
br bb3(%c1 : $Klass)
bb2:
%c2 = apply %f() : $@convention(thin) () -> @owned Klass
br bb3(%c2 : $Klass)
bb3(%arg : @owned $Klass):
%b = begin_borrow %arg : $Klass
%ele = ref_element_addr %b : $Klass, #Klass.val
br bb4
bb4:
%addr = begin_access [read] [dynamic] %ele : $*Int
%ld = load [trivial] %addr : $*Int
end_access %addr : $*Int
cond_br undef, bb4a, bb5
bb4a:
br bb4
bb5:
end_borrow %b : $Klass
destroy_value %arg : $Klass
%z = tuple ()
return %z : $()
}
// CHECK-LABEL: sil [ossa] @test_jump_thread_checked_cast_value :
// CHECK: checked_cast_br
// CHECK: checked_cast_br
// CHECK-LABEL: } // end sil function 'test_jump_thread_checked_cast_value'
sil [ossa] @test_jump_thread_checked_cast_value : $@convention(thin) (@owned AnyKlass, @owned AnyKlass) -> () {
bb0(%0 : @owned $AnyKlass, %1 : @owned $AnyKlass):
cond_br undef, bb1, bb2
bb1:
specify_test "simplify_cfg_try_jump_threading @instruction[2]"
%2 = copy_value %0 : $AnyKlass
br bb6(%2 : $AnyKlass)
bb2:
%3 = copy_value %1 : $AnyKlass
br bb6(%3 : $AnyKlass)
bb6(%4 : @owned $AnyKlass):
destroy_value %0 : $AnyKlass
destroy_value %1 : $AnyKlass
checked_cast_br AnyKlass in %4 : $AnyKlass to Klass, bb7, bb8
bb7(%k : @owned $Klass):
destroy_value %k : $Klass
br bb9
bb8(%fail : @owned $AnyKlass):
destroy_value %fail : $AnyKlass
br bb9
bb9:
%999 = tuple ()
return %999 : $()
}
// Partial apply cannot be cloned, even in OSSA. OSSA lowering does
// not know how to allocate for multiple partial applies.
//
// rdar://119768691 (OwnershipModelEliminator triggers assertion when
// lowering certain [on_stack] partial_applys in certain
// circumstances)
sil @test_simple_jump_thread_clone_partial_apply_closure : $@convention(thin) (@inout_aliasable Klass) -> ()
sil @test_simple_jump_thread_clone_partial_apply_take_closure : $@convention(thin) (@noescape @callee_guaranteed () ->()) -> ()
// CHECK-LABEL: sil [ossa] @test_simple_jump_thread_clone_partial_apply : $@convention(thin) (@owned Klass, @inout Klass) -> Builtin.Int1 {
// CHECK: bb{{.*}}(%{{.*}} : @owned $FakeOptional<Klass>):
// CHECK: partial_apply [callee_guaranteed]
// CHECK-NEXT: mark_dependence
// CHECK-NEXT: begin_borrow [lexical]
// CHECK-NOT: partial_apply [callee_guaranteed]
// CHECK-NOT: begin_borrow
// CHECK-LABEL: } // end sil function 'test_simple_jump_thread_clone_partial_apply'
sil [ossa] @test_simple_jump_thread_clone_partial_apply : $@convention(thin) (@owned Klass, @inout Klass) -> Builtin.Int1 {
bb0(%0 : @owned $Klass, %1 : $*Klass):
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
cond_br undef, bb1, bb2
bb1:
specify_test "simplify_cfg_try_jump_threading @instruction[4]"
%2 = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
br bb3(%2 : $FakeOptional<Klass>)
bb2:
destroy_value %0 : $Klass
%3 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
br bb3(%3 : $FakeOptional<Klass>)
bb3(%4 : @owned $FakeOptional<Klass>):
%5 = select_enum %4 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: %t, case #FakeOptional.none!enumelt: %f : $Builtin.Int1
%6 = function_ref @test_simple_jump_thread_clone_partial_apply_closure : $@convention(thin) (@inout_aliasable Klass) -> ()
%7 = partial_apply [callee_guaranteed] [on_stack] %6(%1) : $@convention(thin) (@inout_aliasable Klass) -> ()
%8 = mark_dependence %7 : $@noescape @callee_guaranteed () ->() on %1 : $*Klass
%9 = begin_borrow [lexical] %8 : $@noescape @callee_guaranteed () ->()
br bb4
bb4:
%func = function_ref @test_simple_jump_thread_clone_partial_apply_take_closure : $@convention(thin) (@noescape @callee_guaranteed () ->()) -> ()
%call = apply %func(%9) : $@convention(thin) (@noescape @callee_guaranteed () ->()) -> ()
end_borrow %9 : $@noescape @callee_guaranteed () ->()
destroy_value %8 : $@noescape @callee_guaranteed () ->()
destroy_value %4 : $FakeOptional<Klass>
return %5 : $Builtin.Int1
}
sil_global @my_global : $S
sil @globalinit_func11 : $@convention(thin) () -> ()
struct S {
}
// This test is not optimized because the dest bb of the branch has a single predecessor
// CHECK-LABEL: sil [ossa] @test_simplify_switch_enum_jump_threading_sil_token :
// CHECK: switch_enum
// CHECK-NOT: switch_enum
// CHECK-LABEL: } // end sil function 'test_simplify_switch_enum_jump_threading_sil_token'
sil [ossa] @test_simplify_switch_enum_jump_threading_sil_token : $@convention(thin) (@owned Klass, Builtin.RawPointer) -> () {
bb0(%0 : @owned $Klass, %1 : $Builtin.RawPointer):
cond_br undef, bb1, bb2
bb1:
specify_test "simplify_cfg_try_jump_threading @instruction[2]"
%s = enum $FakeOptional<Klass>, #FakeOptional.some!enumelt, %0 : $Klass
br bb3(%s : $FakeOptional<Klass>)
bb2:
destroy_value %0 : $Klass
%n = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
br bb3(%n : $FakeOptional<Klass>)
bb3(%3 : @owned $FakeOptional<Klass>):
%f = function_ref @globalinit_func11 : $@convention(thin) () -> ()
%b = builtin "once"(%1 : $Builtin.RawPointer, %f : $@convention(thin) () -> ()) : $Builtin.SILToken
%g = global_addr @my_global : $*S depends_on %b
switch_enum %3 : $FakeOptional<Klass>, case #FakeOptional.some!enumelt: bb5, case #FakeOptional.none!enumelt: bb4
bb4:
br bb6
bb5(%6 : @owned $Klass):
%ld = load [trivial] %g : $*S
apply undef(%ld) : $@convention(thin) (S) -> ()
destroy_value %6 : $Klass
br bb6
bb6:
%t = tuple ()
return %t : $()
}
sil @_swift_stdlib_isNSString : $@convention(c) (AnyObject) -> UInt8
// Ensure no crash in compiler
sil hidden [ossa] @test_clone_destroy_none : $@convention(thin) (@guaranteed AnyObject) -> Bool {
bb0(%0 : @guaranteed $AnyObject):
%3 = enum $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>, #Optional.none!enumelt
%4 = begin_borrow %3 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
switch_enum %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
bb1(%6 : @guaranteed $(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)):
end_borrow %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
%8 = integer_literal $Builtin.Int1, -1
br bb3(%8 : $Builtin.Int1)
bb2:
end_borrow %4 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
%11 = integer_literal $Builtin.Int1, 0
br bb3(%11 : $Builtin.Int1)
bb3(%13 : $Builtin.Int1):
destroy_value %3 : $Optional<(utf16Length: Int, asciiContentsPointer: UnsafePointer<UInt8>, untaggedCocoa: AnyObject)>
cond_br %13, bb4, bb5
bb4:
%16 = integer_literal $Builtin.Int1, -1
%17 = struct $Bool (%16 : $Builtin.Int1)
br bb6(%17 : $Bool)
bb5:
%19 = function_ref @_swift_stdlib_isNSString : $@convention(c) (AnyObject) -> UInt8
%20 = apply %19(%0) : $@convention(c) (AnyObject) -> UInt8
%21 = integer_literal $Builtin.Int8, 0
%22 = struct_extract %20 : $UInt8, #UInt8._value
%23 = builtin "cmp_eq_Int8"(%22 : $Builtin.Int8, %21 : $Builtin.Int8) : $Builtin.Int1
%24 = integer_literal $Builtin.Int1, -1
%25 = builtin "xor_Int1"(%23 : $Builtin.Int1, %24 : $Builtin.Int1) : $Builtin.Int1
%26 = struct $Bool (%25 : $Builtin.Int1)
br bb6(%26 : $Bool)
bb6(%28 : $Bool):
return %28 : $Bool
}