mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
244 lines
4.8 KiB
Plaintext
244 lines
4.8 KiB
Plaintext
// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -compute-dominance-info -compute-loop-info -loop-canonicalizer %s | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
|
|
// CHECK-LABEL: sil @insert_preheader_1 : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: cond_br undef, bb1, bb4
|
|
// CHECK: bb1:
|
|
// CHECK: br bb2
|
|
// CHECK: bb2:
|
|
// CHECK: cond_br undef, bb2, bb3
|
|
// CHECK: bb3:
|
|
// CHECK: br bb4
|
|
// CHECK: bb4:
|
|
// CHECK: return undef
|
|
sil @insert_preheader_1 : $@convention(thin) () -> () {
|
|
bb0:
|
|
cond_br undef, bb1, bb3
|
|
|
|
// A bb will be inserted along the edge from bb0 -> bb1.
|
|
bb1:
|
|
cond_br undef, bb1, bb2
|
|
|
|
// This is the exit block of the loop on bb1. We do this so this test *only*
|
|
// tests the preheader insertion vs the exit block canonicalization.
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
return undef : $()
|
|
}
|
|
|
|
// Make sure that we insert the pre-header correctly given a header with
|
|
// multiple predecessors.
|
|
//
|
|
// CHECK-LABEL: sil @insert_preheader_2 : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: cond_br undef, bb1, [[PREHEADER:bb[0-9]+]]
|
|
// CHECK: bb1:
|
|
// CHECK: br [[PREHEADER]]
|
|
// CHECK: [[PREHEADER]]:
|
|
// CHECK: br bb3
|
|
// CHECK: bb3:
|
|
// CHECK: cond_br undef, bb3, bb4
|
|
// CHECK: return undef : $()
|
|
sil @insert_preheader_2 : $@convention(thin) () -> () {
|
|
bb0:
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb3:
|
|
return undef : $()
|
|
}
|
|
|
|
// Make sure that we can handle pre-header insertion for loops in sequence
|
|
// (i.e. where one loop branches into another loop) correctly in terms of
|
|
// updating loop info.
|
|
//
|
|
// CHECK-LABEL: sil @insert_preheader_3 : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: cond_br undef, bb1, bb4
|
|
// CHECK: bb1:
|
|
// CHECK: br bb2
|
|
// CHECK: bb2:
|
|
// CHECK: cond_br undef, bb2, bb3
|
|
// CHECK: bb3:
|
|
// CHECK: br bb7
|
|
// CHECK: bb4:
|
|
// CHECK: br bb5
|
|
// CHECK: bb5:
|
|
// CHECK: cond_br undef, bb5, bb6
|
|
// CHECK: bb6:
|
|
// CHECK: br bb7
|
|
// CHECK: bb7
|
|
// CHECK: br bb8
|
|
// CHECK: bb8:
|
|
// CHECK: cond_br undef, bb8, bb9
|
|
// CHECK: bb9:
|
|
// CHECK: return undef
|
|
sil @insert_preheader_3 : $@convention(thin) () -> () {
|
|
bb0:
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
cond_br undef, bb1, bb3
|
|
|
|
bb2:
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb3:
|
|
cond_br undef, bb3, bb4
|
|
|
|
bb4:
|
|
return undef : $()
|
|
}
|
|
|
|
// Make sure that we insert pre-headers correctly for nested loops I am using
|
|
// patterns in more places than I need to, to make the test case more obvious to
|
|
// the reader.
|
|
//
|
|
// CHECK-LABEL: sil @insert_preheader_4 : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: br bb1
|
|
// CHECK: bb1:
|
|
// CHECK: cond_br undef, bb2, [[PREHEADER_1:bb[0-9]+]]
|
|
// CHECK: bb2:
|
|
// CHECK: br [[PREHEADER_1]]
|
|
// First pre-header
|
|
// CHECK: [[PREHEADER_1]]:
|
|
// CHECK: br bb4
|
|
// CHECK: bb4:
|
|
// CHECK: cond_br undef, bb8, [[PREHEADER_2:bb[0-9]+]]
|
|
// CHECK: [[PREHEADER_2]]:
|
|
// CHECK: br bb6
|
|
// CHECK: bb6:
|
|
// CHECK: cond_br undef, bb6, bb7
|
|
// This is an exit bb for bb6.
|
|
// CHECK: bb7:
|
|
// CHECK: cond_br undef, bb8, bb9
|
|
// CHECK: bb8:
|
|
// CHECK: br bb4
|
|
// CHECK: bb9:
|
|
// CHECK: return undef
|
|
sil @insert_preheader_4 : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
cond_br undef, bb3, bb4
|
|
|
|
bb4:
|
|
cond_br undef, bb4, bb5
|
|
|
|
bb5:
|
|
cond_br undef, bb3, bb6
|
|
|
|
bb6:
|
|
return undef : $()
|
|
}
|
|
|
|
// Test insertBackedgeBlock.
|
|
//
|
|
// CHECK-LABEL: insert_backedge_block
|
|
// CHECK: bb2:
|
|
// CHECK: cond_br undef, bb3, bb4
|
|
// CHECK: bb3:
|
|
// CHECK: br bb1
|
|
// CHECK: bb4:
|
|
// CHECK: cond_br undef, bb3, bb5
|
|
sil @insert_backedge_block : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
cond_br undef, bb1, bb3
|
|
|
|
bb3:
|
|
cond_br undef, bb1, bb4
|
|
|
|
bb4:
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () {
|
|
// CHECK: bb1:
|
|
// CHECK: br bb2
|
|
// CHECK: bb2:
|
|
// CHECK: br bb3
|
|
// CHECK: bb3:
|
|
// CHECK: cond_br undef, bb4, bb5
|
|
// CHECK: bb4:
|
|
// CHECK: br bb2
|
|
// CHECK: bb5:
|
|
// CHECK: cond_br undef, bb4, bb6
|
|
// CHECK: bb6:
|
|
// CHECK: cond_br undef, bb1, bb7
|
|
// CHECK: bb7:
|
|
// CHECK: return undef
|
|
sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
cond_br undef, bb2, bb4
|
|
|
|
bb4:
|
|
cond_br undef, bb2, bb5
|
|
|
|
bb5:
|
|
cond_br undef, bb1, bb6
|
|
|
|
bb6:
|
|
return undef : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () {
|
|
// CHECK: bb0:
|
|
// CHECK: cond_br undef, bb1, bb4
|
|
// CHECK: bb1:
|
|
// CHECK: br bb2
|
|
// CHECK: bb2:
|
|
// CHECK: cond_br undef, bb2, bb3
|
|
// CHECK: bb3:
|
|
// CHECK: br bb4
|
|
// CHECK: bb4:
|
|
// CHECK: return undef
|
|
sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () {
|
|
bb0:
|
|
cond_br undef, bb1, bb3
|
|
|
|
// Header
|
|
bb1:
|
|
br bb2
|
|
|
|
bb2:
|
|
cond_br undef, bb2, bb3
|
|
|
|
// Exit with multiple predecessors. The edge from bb2 -> bb3 will be split.
|
|
bb3:
|
|
return undef : $()
|
|
}
|