1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplify-cfg | %FileCheck %s
// Tests tryJumpThreading with OSSA for trivial branch and terminator
// arguments. This does not require -jumpthread-simplify-cfg, which
// is only for dominator-based jump-threading.
sil_stage canonical
import Builtin
import Swift
internal enum Enum {
case one
case two
case three
}
enum BoolLike { case true_, false_ }
// Test that SimplifyCFG::simplifyBlocks, tryJumpThreading does not
// perform unbounded loop peeling.
//
// rdar://73357726
// https://github.com/apple/swift/issues/56457
// Compiling with optimisation runs indefinitely for grpc-swift
//
// Note: this no longer attempts to run jump-threading infinitely, so
// does not actually unit test the bailout. But it is still an
// interesting test case.
//
// CHECK-LABEL: sil [ossa] @testInfinitePeeling : $@convention(method) (Builtin.Int64, Enum) -> () {
//
// There is only one switch_enum blocks, and it is no longer in a loop.
// CHECK: bb0(%0 : $Builtin.Int64, %1 : $Enum):
// CHECK: switch_enum %1 : $Enum, case #Enum.one!enumelt: bb4, default bb1
// CHECK: bb1(%{{.*}} : $Enum):
// CHECK: br bb5
// CHECK: bb2:
// CHECK: br bb6
//
// CHECK: bb3:
// CHECK: br bb5
//
// This is the cond_br block after jump-threading.
// CHECK: bb4:
// CHECK: cond_br %{{.*}}, bb3, bb2
//
// The original loop has been removed here.
// CHECK: bb5:
// CHECK: br bb6
//
// CHECK: bb6:
// CHECK: return
// CHECK-LABEL: } // end sil function 'testInfinitePeeling'
sil [ossa] @testInfinitePeeling : $@convention(method) (Builtin.Int64, Enum) -> () {
bb0(%0 : $Builtin.Int64, %1 : $Enum):
%2 = integer_literal $Builtin.Int64, 99999999
br bb1(%0 : $Builtin.Int64, %1 : $Enum)
bb1(%4 : $Builtin.Int64, %5 : $Enum):
switch_enum %5 : $Enum, case #Enum.one!enumelt: bb4, default bb5
bb2(%7 : $Builtin.Int64, %8 : $Enum):
%9 = builtin "cmp_slt_Int64"(%2 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1
cond_br %9, bb3, bb6
bb3:
br bb1(%7 : $Builtin.Int64, %8 : $Enum)
bb4:
%12 = integer_literal $Builtin.Int64, 1
%13 = integer_literal $Builtin.Int1, -1
%14 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %12 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0
%16 = enum $Enum, #Enum.two!enumelt
br bb2(%15 : $Builtin.Int64, %16 : $Enum)
bb5(%17 : $Enum):
br bb2(%2 : $Builtin.Int64, %17 : $Enum)
bb6:
%19 = tuple ()
return %19 : $()
}
class C {
@_hasStorage @_hasInitialValue var field: Int { get set }
init()
}
// func testThread2(a : Int32) -> Int32 {
// enum b = (a ? _true : _false)
// if b == _true { return 42 } else { return 17 }
//
/// CHECK-LABEL: sil [ossa] @testThread2
/// CHECK: bb0([[COND:%.*]] : {{.*}}):
/// CHECK: cond_br [[COND]], bb1, bb2
/// CHECK: bb1:
/// CHECK: integer_literal $Builtin.Int64, 42
/// CHeCK: br bb3
/// CHECK: bb2:
/// CHECK: integer_literal $Builtin.Int64, 17
/// CHECK: br bb3
/// CHECK: bb3
/// CHECK: return
sil [ossa] @testThread2 : $@convention(thin) (Builtin.Int1) -> Int64 {
bb0(%0 : $Builtin.Int1):
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
cond_br %0, bb1, bb2
bb1:
%4 = enum $BoolLike, #BoolLike.true_!enumelt
br bb3(%4 : $BoolLike)
bb2:
%8 = enum $BoolLike, #BoolLike.false_!enumelt
br bb3(%8 : $BoolLike)
bb3(%6 : $BoolLike):
%100 = select_enum %6 : $BoolLike, case #BoolLike.true_!enumelt: %t, case #BoolLike.false_!enumelt: %f : $Builtin.Int1
br bb4
bb4:
cond_br %100, bb5, bb6
bb5:
%11 = metatype $@thin Int64.Type
%12 = integer_literal $Builtin.Int64, 42
%13 = struct $Int64 (%12 : $Builtin.Int64)
br bb7(%13 : $Int64)
bb6:
%15 = metatype $@thin Int64.Type
%16 = integer_literal $Builtin.Int64, 17
%17 = struct $Int64 (%16 : $Builtin.Int64)
br bb7(%17 : $Int64)
bb7(%19 : $Int64):
return %19 : $Int64
}
|