mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
I am doing this separately from the actual change to eliminate the option to make it easier to review.
262 lines
8.2 KiB
Plaintext
262 lines
8.2 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all -dce %s | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
// CHECK-LABEL: sil @dead1
|
|
sil @dead1 : $@convention(thin) (Int32, Int32) -> Int32 {
|
|
// CHECK: bb0
|
|
bb0(%0 : $Int32, %1 : $Int32):
|
|
%3 = struct_extract %0 : $Int32, #Int32._value
|
|
%4 = struct_extract %1 : $Int32, #Int32._value
|
|
%5 = integer_literal $Builtin.Int1, -1
|
|
%6 = builtin "sadd_with_overflow_Int32"(%3 : $Builtin.Int32, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%7 = tuple_extract %6 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%8 = struct $Int32 (%7 : $Builtin.Int32)
|
|
// CHECK-NEXT: return %0
|
|
return %0 : $Int32
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dead2
|
|
sil @dead2 : $@convention(thin) () -> () {
|
|
// CHECK: bb0
|
|
bb0:
|
|
// CHECK-NOT: integer_literal $Builtin.Int32, 2
|
|
%0 = integer_literal $Builtin.Int32, 2
|
|
// CHECK-NOT: integer_literal $Builtin.Int32, 0
|
|
%1 = integer_literal $Builtin.Int32, 0
|
|
// CHECK-NEXT: br bb1
|
|
br bb1(%0 : $Builtin.Int32, %1 : $Builtin.Int32)
|
|
|
|
// CHECK: bb1
|
|
bb1(%3 : $Builtin.Int32, %4 : $Builtin.Int32):
|
|
// CHECK-NEXT: br bb3
|
|
%5 = integer_literal $Builtin.Int32, 100
|
|
%7 = builtin "cmp_slt_Int32"(%4 : $Builtin.Int32, %5 : $Builtin.Int32) : $Builtin.Int1
|
|
cond_br %7, bb2, bb3
|
|
|
|
// CHECK: bb2
|
|
bb2:
|
|
// CHECK-NEXT: br bb1
|
|
%9 = integer_literal $Builtin.Int32, 3
|
|
%11 = integer_literal $Builtin.Int1, -1
|
|
%12 = builtin "sadd_with_overflow_Int32"(%3 : $Builtin.Int32, %9 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%13 = tuple_extract %12 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%14 = integer_literal $Builtin.Int32, 1
|
|
%15 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %14 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%16 = tuple_extract %15 : $(Builtin.Int32, Builtin.Int1), 0
|
|
br bb1(%13 : $Builtin.Int32, %16 : $Builtin.Int32)
|
|
|
|
// CHECK: bb3
|
|
bb3:
|
|
// CHECK-NEXT: [[RESULT:%[a-zA-Z0-9]+]] = tuple ()
|
|
%18 = tuple ()
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
return %18 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dead3
|
|
sil @dead3 : $@convention(thin) () -> () {
|
|
bb0:
|
|
// CHECK: bb0
|
|
br bb1
|
|
// CHECK: bb1
|
|
bb1:
|
|
// CHECK: bb1:
|
|
// CHECK-NEXT: br bb1
|
|
%0 = integer_literal $Builtin.Int32, 0
|
|
br bb1
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden @test_dce_bbargs
|
|
sil hidden @test_dce_bbargs : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 0
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
%2 = integer_literal $Builtin.Int32, 0
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32)
|
|
%4 = integer_literal $Builtin.Int32, 0
|
|
%5 = struct $Int32 (%4 : $Builtin.Int32)
|
|
%6 = integer_literal $Builtin.Int32, 0
|
|
%7 = struct $Int32 (%6 : $Builtin.Int32)
|
|
%8 = integer_literal $Builtin.Int32, 0
|
|
%9 = struct $Int32 (%8 : $Builtin.Int32)
|
|
%10 = integer_literal $Builtin.Int32, 0
|
|
%11 = struct $Int32 (%10 : $Builtin.Int32)
|
|
br bb1(%1 : $Int32, %3 : $Int32, %11 : $Int32, %7 : $Int32, %9 : $Int32)
|
|
|
|
bb1(%13 : $Int32, %14 : $Int32, %15 : $Int32, %16 : $Int32, %17 : $Int32):
|
|
%18 = integer_literal $Builtin.Int32, 11
|
|
%20 = struct_extract %15 : $Int32, #Int32._value
|
|
%21 = builtin "cmp_slt_Int32"(%20 : $Builtin.Int32, %18 : $Builtin.Int32) : $Builtin.Int1
|
|
%22 = struct $Bool (%21 : $Builtin.Int1)
|
|
%23 = struct_extract %22 : $Bool, #Bool._value
|
|
cond_br %23, bb2, bb10
|
|
|
|
// CHECK: bb2:
|
|
bb2:
|
|
%25 = integer_literal $Builtin.Int32, 0
|
|
%26 = struct $Int32 (%25 : $Builtin.Int32)
|
|
// br bb3(undef : $Int32, undef : $Int32,
|
|
br bb3(%13 : $Int32, %14 : $Int32, %26 : $Int32, %17 : $Int32)
|
|
|
|
bb3(%28 : $Int32, %29 : $Int32, %30 : $Int32, %31 : $Int32):
|
|
%32 = integer_literal $Builtin.Int32, 22
|
|
%34 = struct_extract %30 : $Int32, #Int32._value
|
|
%35 = builtin "cmp_slt_Int32"(%34 : $Builtin.Int32, %32 : $Builtin.Int32) : $Builtin.Int1
|
|
%36 = struct $Bool (%35 : $Builtin.Int1)
|
|
%37 = struct_extract %36 : $Bool, #Bool._value
|
|
cond_br %37, bb4, bb9
|
|
|
|
// CHECK: bb4:
|
|
bb4:
|
|
%39 = integer_literal $Builtin.Int32, 0
|
|
%41 = struct_extract %28 : $Int32, #Int32._value
|
|
%42 = builtin "cmp_eq_Int32"(%39 : $Builtin.Int32, %41 : $Builtin.Int32) : $Builtin.Int1
|
|
%43 = struct $Bool (%42 : $Builtin.Int1)
|
|
%44 = struct_extract %43 : $Bool, #Bool._value
|
|
// CHECK-NOT: cond_br
|
|
// CHECK: br bb8
|
|
cond_br %44, bb5, bb6(%28 : $Int32)
|
|
|
|
bb5:
|
|
%46 = integer_literal $Builtin.Int32, 0
|
|
%47 = struct $Int32 (%46 : $Builtin.Int32)
|
|
br bb6(%47 : $Int32)
|
|
|
|
// CHECK: bb6{{.*}}):
|
|
bb6(%49 : $Int32):
|
|
%50 = integer_literal $Builtin.Int32, 10
|
|
%52 = struct_extract %29 : $Int32, #Int32._value
|
|
%53 = builtin "cmp_eq_Int32"(%50 : $Builtin.Int32, %52 : $Builtin.Int32) : $Builtin.Int1
|
|
%54 = struct $Bool (%53 : $Builtin.Int1)
|
|
%55 = struct_extract %54 : $Bool, #Bool._value
|
|
// CHECK-NOT: cond_br
|
|
// CHECK: br bb8
|
|
cond_br %55, bb7, bb8(%29 : $Int32)
|
|
|
|
// CHECK: bb7:
|
|
bb7:
|
|
%57 = integer_literal $Builtin.Int32, 0
|
|
%58 = struct $Int32 (%57 : $Builtin.Int32)
|
|
// CHECK: br bb8
|
|
br bb8(%58 : $Int32)
|
|
|
|
// CHECK: bb8(%{{[0-9]+}} : $Int32):
|
|
bb8(%60 : $Int32):
|
|
%61 = struct_extract %31 : $Int32, #Int32._value
|
|
%62 = integer_literal $Builtin.Int32, 1
|
|
%64 = integer_literal $Builtin.Int1, -1
|
|
// CHECK-NOT: builtin "sadd_with_overflow_Int32"
|
|
// CHECK-NOT: cond_fail
|
|
%65 = builtin "sadd_with_overflow_Int32"(%61 : $Builtin.Int32, %62 : $Builtin.Int32, %64 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%66 = tuple_extract %65 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%67 = tuple_extract %65 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %67 : $Builtin.Int1
|
|
%69 = struct $Int32 (%66 : $Builtin.Int32)
|
|
%70 = struct_extract %30 : $Int32, #Int32._value
|
|
%71 = integer_literal $Builtin.Int32, 1
|
|
%73 = integer_literal $Builtin.Int1, -1
|
|
// CHECK: builtin "ssub_with_overflow_Int32"
|
|
%74 = builtin "ssub_with_overflow_Int32"(%70 : $Builtin.Int32, %71 : $Builtin.Int32, %73 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%75 = tuple_extract %74 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%76 = tuple_extract %74 : $(Builtin.Int32, Builtin.Int1), 1
|
|
// CHECK: cond_fail
|
|
cond_fail %76 : $Builtin.Int1
|
|
%78 = struct $Int32 (%75 : $Builtin.Int32)
|
|
%tif = function_ref @take_int32 : $@convention(thin) (Int32) -> ()
|
|
%atif = apply %tif(%78) : $@convention(thin) (Int32) -> ()
|
|
// CHECK: br bb3(undef : $Int32, undef : $Int32,
|
|
br bb3(%49 : $Int32, %60 : $Int32, %78 : $Int32, %69 : $Int32)
|
|
|
|
// CHECK: bb9:
|
|
bb9:
|
|
%80 = struct_extract %15 : $Int32, #Int32._value
|
|
%81 = integer_literal $Builtin.Int32, 1
|
|
%83 = integer_literal $Builtin.Int1, -1
|
|
%84 = builtin "sadd_with_overflow_Int32"(%80 : $Builtin.Int32, %81 : $Builtin.Int32, %83 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
|
|
%85 = tuple_extract %84 : $(Builtin.Int32, Builtin.Int1), 0
|
|
%86 = tuple_extract %84 : $(Builtin.Int32, Builtin.Int1), 1
|
|
cond_fail %86 : $Builtin.Int1
|
|
%88 = struct $Int32 (%85 : $Builtin.Int32)
|
|
// CHECK: br bb1(undef : $Int32, undef : $Int32,
|
|
br bb1(%28 : $Int32, %29 : $Int32, %88 : $Int32, %30 : $Int32, %31 : $Int32)
|
|
|
|
// CHECK: bb10:
|
|
bb10:
|
|
%90 = tuple ()
|
|
// CHECK: return
|
|
return %90 : $()
|
|
}
|
|
|
|
sil @take_int32 : $@convention(thin) (Int32) -> ()
|
|
|
|
// CHECK-LABEL: sil @remove_fix_lifetime
|
|
// CHECK: bb0:
|
|
// CHECK-NEXT: tuple
|
|
// CHECK-NEXT: return
|
|
sil @remove_fix_lifetime : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 0
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
|
|
fix_lifetime %1 : $Int32
|
|
fix_lifetime %1 : $Int32
|
|
|
|
%90 = tuple ()
|
|
return %90 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_remove_fix_lifetime
|
|
// CHECK: fix_lifetime
|
|
// CHECK: fix_lifetime
|
|
// CHECK: return
|
|
sil @dont_remove_fix_lifetime : $@convention(thin) () -> Int32 {
|
|
bb0:
|
|
%0 = integer_literal $Builtin.Int32, 0
|
|
%1 = struct $Int32 (%0 : $Builtin.Int32)
|
|
|
|
fix_lifetime %1 : $Int32
|
|
fix_lifetime %1 : $Int32
|
|
|
|
return %1 : $Int32
|
|
}
|
|
|
|
struct Container {
|
|
var i: Int32
|
|
}
|
|
|
|
// CHECK-LABEL: sil @dont_remove_addr_fix_lifetime
|
|
// CHECK: fix_lifetime
|
|
// CHECK: fix_lifetime
|
|
// CHECK: return
|
|
sil @dont_remove_addr_fix_lifetime : $@convention(thin) (@in Container) -> () {
|
|
bb0(%0 : $*Container):
|
|
%1 = struct_element_addr %0 : $*Container, #Container.i
|
|
|
|
fix_lifetime %1 : $*Int32
|
|
fix_lifetime %1 : $*Int32
|
|
|
|
%90 = tuple ()
|
|
return %90 : $()
|
|
}
|
|
|
|
// Check that DCE does not crash with an infinite loop through a cond_br.
|
|
// CHECK-LABEL: sil @deal_with_infinite_loop
|
|
// CHECK: cond_br
|
|
sil @deal_with_infinite_loop : $@convention(thin) () -> () {
|
|
bb0:
|
|
br bb1
|
|
|
|
bb1:
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
br bb1
|
|
|
|
bb3:
|
|
br bb1
|
|
}
|