blob: 560fe218dfeef11c36707b8d0e7125188c2a127f [file] [log] [blame]
// RUN: %target-sil-opt -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 : $()
}