Files
swift-mirror/test/SILOptimizer/redundant_phi_elimination_ossa.sil
Erik Eckstein f363c3296e SIL: change the textual SIL output of a re-borrow phi from @reborrow @guaranteed to @reborrow
It's redundant because only guaranteed phis can be reborrows.
2024-11-13 10:39:14 +01:00

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 : $()
}