mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
246 lines
7.6 KiB
Plaintext
246 lines
7.6 KiB
Plaintext
// RUN: %target-sil-opt -enable-sil-verify-all %s -update-borrowed-from -redundant-phi-elimination | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
class Klass {
|
|
}
|
|
|
|
struct NonTrivialStruct {
|
|
var val:Klass
|
|
}
|
|
|
|
public enum FakeOptional<T> {
|
|
case none
|
|
case some(T)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg1 :
|
|
// CHECK: bb3([[ARG1:%.*]] : @owned $FakeOptional<Klass>):
|
|
// CHECK: [[COPY:%.*]] = copy_value [[ARG1]]
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg1'
|
|
sil [ossa] @test_redundantownedphiarg1 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : @owned $FakeOptional<Klass>):
|
|
destroy_value %1 : $FakeOptional<Klass>
|
|
destroy_value %2 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg2 :
|
|
// CHECK: bb3([[ARG1:%.*]] : $FakeOptional<Klass>):
|
|
// CHECK-NOT: copy_value
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg2'
|
|
sil [ossa] @test_redundantownedphiarg2 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : $FakeOptional<Klass>):
|
|
destroy_value %1 : $FakeOptional<Klass>
|
|
destroy_value %2 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg3 :
|
|
// CHECK: bb3([[ARG1:%.*]] : $FakeOptional<Klass>):
|
|
// CHECK-NOT: copy_value
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg3'
|
|
sil [ossa] @test_redundantownedphiarg3 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : $FakeOptional<Klass>):
|
|
destroy_value %1 : $FakeOptional<Klass>
|
|
cond_br undef, bb4, bb5
|
|
|
|
bb4:
|
|
destroy_value %2 : $FakeOptional<Klass>
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg4 :
|
|
// CHECK: bb3([[ARG1:%.*]] : $FakeOptional<Klass>):
|
|
// CHECK-NOT: copy_value
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg4'
|
|
sil [ossa] @test_redundantownedphiarg4 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : $FakeOptional<Klass>, %2 : @owned $FakeOptional<Klass>):
|
|
destroy_value %1 : $FakeOptional<Klass>
|
|
destroy_value %2 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg5 :
|
|
// CHECK: bb1([[ARG1:%.*]] : @owned $FakeOptional<Klass>):
|
|
// CHECK: [[COPY1:%.*]] = copy_value [[ARG1]]
|
|
// CHECK: bb3([[ARG2:%.*]] : @owned $FakeOptional<Klass>):
|
|
// CHECK: [[COPY2:%.*]] = copy_value [[ARG2]]
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg5'
|
|
sil [ossa] @test_redundantownedphiarg5 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb2, bb4
|
|
|
|
bb1(%3 : @owned $FakeOptional<Klass>, %4 : @owned $FakeOptional<Klass>):
|
|
destroy_value %3 : $FakeOptional<Klass>
|
|
destroy_value %4 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : @owned $FakeOptional<Klass>):
|
|
br bb1(%1 : $FakeOptional<Klass>, %2 : $FakeOptional<Klass>)
|
|
|
|
bb4:
|
|
br bb1(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
}
|
|
|
|
|
|
// Redundant phi args in bb4 don't get optimized away, because a compensating copy_value is added
|
|
// while optimizing the redundant phi args in bb3.
|
|
// CHECK-LABEL: sil [ossa] @test_redundantownedphiarg6 :
|
|
// CHECK: bb3([[ARG1:%.*]] : @owned $FakeOptional<Klass>):
|
|
// CHECK: [[COPY1:%.*]] = copy_value [[ARG1]]
|
|
// CHECK: bb4([[ARG2:%.*]] : @owned $FakeOptional<Klass>, [[ARG3:%.*]] : @owned $FakeOptional<Klass>):
|
|
// CHECK-NOT: [[COPY2:%.*]] = copy_value [[ARG1]]
|
|
// CHECK-LABEL: } // end sil function 'test_redundantownedphiarg6'
|
|
sil [ossa] @test_redundantownedphiarg6 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb4(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : @owned $FakeOptional<Klass>):
|
|
br bb4(%1 : $FakeOptional<Klass>, %2 : $FakeOptional<Klass>)
|
|
|
|
bb4(%3 : @owned $FakeOptional<Klass>, %4 : @owned $FakeOptional<Klass>):
|
|
destroy_value %3 : $FakeOptional<Klass>
|
|
destroy_value %4 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantguaranteedphiarg1 :
|
|
// CHECK: bb3([[ARG1:%.*]] : @guaranteed $FakeOptional<Klass>, [[ARG2:%.*]] : @guaranteed $FakeOptional<Klass>):
|
|
// CHECK-LABEL: } // end sil function 'test_redundantguaranteedphiarg1'
|
|
sil [ossa] @test_redundantguaranteedphiarg1 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %0 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @guaranteed $FakeOptional<Klass>, %2 : @guaranteed $FakeOptional<Klass>):
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantguaranteedphiarg2 :
|
|
// CHECK: bb3([[ARG1:%.*]] : @owned $FakeOptional<Klass>, [[ARG2:%.*]] : @reborrow $FakeOptional<Klass>):
|
|
// CHECK-LABEL: } // end sil function 'test_redundantguaranteedphiarg2'
|
|
sil [ossa] @test_redundantguaranteedphiarg2 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
%b = begin_borrow %0 : $FakeOptional<Klass>
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%0 : $FakeOptional<Klass>, %b : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%0 : $FakeOptional<Klass>, %b : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @owned $FakeOptional<Klass>, %2 : @guaranteed $FakeOptional<Klass>):
|
|
end_borrow %2 : $FakeOptional<Klass>
|
|
destroy_value %1 : $FakeOptional<Klass>
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_redundantguaranteedphiarg3 :
|
|
// CHECK: bb3([[ARG3:%.*]] : @reborrow $FakeOptional<Klass>, [[ARG2:%.*]] : @reborrow $FakeOptional<Klass>):
|
|
// CHECK-LABEL: } // end sil function 'test_redundantguaranteedphiarg3'
|
|
sil [ossa] @test_redundantguaranteedphiarg3 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = enum $FakeOptional<Klass>, #FakeOptional.none!enumelt
|
|
%b1 = begin_borrow %0 : $FakeOptional<Klass>
|
|
%b2 = begin_borrow %0 : $FakeOptional<Klass>
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
br bb3(%b1 : $FakeOptional<Klass>, %b2 : $FakeOptional<Klass>)
|
|
|
|
bb2:
|
|
br bb3(%b1 : $FakeOptional<Klass>, %b2 : $FakeOptional<Klass>)
|
|
|
|
bb3(%1 : @guaranteed $FakeOptional<Klass>, %2 : @guaranteed $FakeOptional<Klass>):
|
|
cond_br undef, bb4, bb5
|
|
|
|
bb4:
|
|
end_borrow %1 : $FakeOptional<Klass>
|
|
end_borrow %2 : $FakeOptional<Klass>
|
|
br bb6
|
|
|
|
bb5:
|
|
end_borrow %2 : $FakeOptional<Klass>
|
|
end_borrow %1 : $FakeOptional<Klass>
|
|
br bb6
|
|
|
|
bb6:
|
|
%res = tuple ()
|
|
return %res : $()
|
|
}
|
|
|