Files
swift-mirror/test/SILOptimizer/redundant_phi_elimination.sil
Erik Eckstein 93a0dfc578 SILOptimizer: a new small optimization pass to remove redundant basic block arguments.
RedundantPhiElimination eliminates block phi-arguments which have the same value as other arguments of the same block.
This also works with cycles, like two equivalent loop induction variables. Such patterns are generated e.g. when using stdlib's enumerated() on Array.

   preheader:
     br bb1(%initval, %initval)
   header(%phi1, %phi2):
     %next1 = builtin "add" (%phi1, %one)
     %next2 = builtin "add" (%phi2, %one)
     cond_br %loopcond, header(%next1, %next2), exit
   exit:

is replaced with

   preheader:
     br bb1(%initval)
   header(%phi1):
     %next1 = builtin "add" (%phi1, %one)
     %next2 = builtin "add" (%phi1, %one) // dead: will be cleaned-up later
     cond_br %loopcond, header(%next1), exit
   exit:

Any remaining dead or "trivially" equivalent instructions will then be cleaned-up by DCE and CSE, respectively.

rdar://problem/33438123
2020-03-26 19:30:01 +01:00

156 lines
5.6 KiB
Plaintext

// RUN: %target-sil-opt -enable-sil-verify-all %s -redundant-phi-elimination | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
// CHECK-LABEL: sil @test_simple
// CHECK: bb1:
// CHECK: br bb3(%0 : $Builtin.Int64)
// CHECK: bb2:
// CHECK: br bb3(%1 : $Builtin.Int64)
// CHECK: bb3([[ARG:%[0-9]+]] : $Builtin.Int64):
// CHECK: builtin "sadd_with_overflow_Int64"([[ARG]] : $Builtin.Int64, [[ARG]] : $Builtin.Int64,
// CHECK: } // end sil function 'test_simple'
sil @test_simple : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
%2 = integer_literal $Builtin.Int1, -1
cond_br undef, bb1, bb2
bb1:
br bb3(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
bb2:
br bb3(%1 : $Builtin.Int64, %1 : $Builtin.Int64)
bb3(%4 : $Builtin.Int64, %5 : $Builtin.Int64):
%6 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %5 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%8 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %8 : $Builtin.Int1, "arithmetic overflow"
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_not_equal
// CHECK: bb1:
// CHECK: br bb3(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
// CHECK: bb2:
// CHECK: br bb3(%0 : $Builtin.Int64, %1 : $Builtin.Int64)
// CHECK: bb3([[ARG1:%[0-9]+]] : $Builtin.Int64, [[ARG2:%[0-9]+]] : $Builtin.Int64):
// CHECK: builtin "sadd_with_overflow_Int64"([[ARG1]] : $Builtin.Int64, [[ARG2]] : $Builtin.Int64,
// CHECK: } // end sil function 'test_not_equal'
sil @test_not_equal : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
%2 = integer_literal $Builtin.Int1, -1
cond_br undef, bb1, bb2
bb1:
br bb3(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
bb2:
br bb3(%0 : $Builtin.Int64, %1 : $Builtin.Int64)
bb3(%4 : $Builtin.Int64, %5 : $Builtin.Int64):
%6 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %5 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%8 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %8 : $Builtin.Int1, "arithmetic overflow"
%r = tuple ()
return %r : $()
}
sil @unknown : $@convention(thin) () -> Builtin.Int64
// CHECK-LABEL: sil @test_side_effects
// CHECK: [[A1:%[0-9]+]] = apply
// CHECK: [[A2:%[0-9]+]] = apply
// CHECK: br bb1([[A1]] : $Builtin.Int64, [[A2]] : $Builtin.Int64)
// CHECK: bb1([[ARG1:%[0-9]+]] : $Builtin.Int64, [[ARG2:%[0-9]+]] : $Builtin.Int64):
// CHECK: builtin "sadd_with_overflow_Int64"([[ARG1]] : $Builtin.Int64, [[ARG2]] : $Builtin.Int64,
// CHECK: } // end sil function 'test_side_effects'
sil @test_side_effects : $@convention(thin) () -> () {
bb0:
%f = function_ref @unknown : $@convention(thin) () -> Builtin.Int64
%0 = apply %f() : $@convention(thin) () -> Builtin.Int64
%1 = apply %f() : $@convention(thin) () -> Builtin.Int64
%2 = integer_literal $Builtin.Int1, -1
br bb1(%0 : $Builtin.Int64, %1 : $Builtin.Int64)
bb1(%4 : $Builtin.Int64, %5 : $Builtin.Int64):
%6 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %5 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%8 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %8 : $Builtin.Int1, "arithmetic overflow"
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_loop
// CHECK: br bb1(%0 : $Builtin.Int64)
// CHECK: bb1([[ARG:%[0-9]+]] : $Builtin.Int64):
// CHECK: [[S1:%[0-9]+]] = builtin "sadd_with_overflow_Int64"([[ARG]] : $Builtin.Int64,
// CHECK: [[T1:%[0-9]+]] = tuple_extract [[S1]] {{.*}}, 0
// CHECK: [[T2:%[0-9]+]] = tuple_extract [[S1]] {{.*}}, 1
// CHECK: cond_fail [[T2]]
// CHECK: [[S2:%[0-9]+]] = builtin "sadd_with_overflow_Int64"([[ARG]] : $Builtin.Int64,
// CHECK: [[T3:%[0-9]+]] = tuple_extract [[S2]] {{.*}}, 1
// CHECK: cond_fail [[T3]]
// CHECK: bb2:
// CHECK: br bb1([[T1]] : $Builtin.Int64)
// CHECK: } // end sil function 'test_loop'
sil @test_loop : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
%2 = integer_literal $Builtin.Int1, -1
br bb1(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
bb1(%4 : $Builtin.Int64, %5 : $Builtin.Int64):
%6 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%7 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 0
%8 = tuple_extract %6 : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %8 : $Builtin.Int1, "arithmetic overflow"
%10 = builtin "sadd_with_overflow_Int64"(%5 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
%11 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 0
%12 = tuple_extract %10 : $(Builtin.Int64, Builtin.Int1), 1
cond_fail %12 : $Builtin.Int1, "arithmetic overflow"
cond_br undef, bb2, bb3
bb2:
br bb1(%7 : $Builtin.Int64, %11 : $Builtin.Int64)
bb3:
%r = tuple ()
return %r : $()
}
// CHECK-LABEL: sil @test_mismatching_arg
// CHECK: br bb1(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
// CHECK: bb1([[ARG1:%[0-9]+]] : $Builtin.Int64, {{%[0-9]+}} : $Builtin.Int64):
// CHECK: bb2:
// CHECK: br bb1([[ARG1]] : $Builtin.Int64, %1 : $Builtin.Int64)
// CHECK: } // end sil function 'test_mismatching_arg'
sil @test_mismatching_arg : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int64, 0
%1 = integer_literal $Builtin.Int64, 1
br bb1(%0 : $Builtin.Int64, %0 : $Builtin.Int64)
bb1(%4 : $Builtin.Int64, %5 : $Builtin.Int64):
cond_br undef, bb2, bb3
bb2:
br bb1(%4 : $Builtin.Int64, %1 : $Builtin.Int64)
bb3:
%r = tuple ()
return %r : $()
}