diff --git a/lib/SILOptimizer/Transforms/ConditionForwarding.cpp b/lib/SILOptimizer/Transforms/ConditionForwarding.cpp index 00eb7e35f0554..8f55e7162b88f 100644 --- a/lib/SILOptimizer/Transforms/ConditionForwarding.cpp +++ b/lib/SILOptimizer/Transforms/ConditionForwarding.cpp @@ -290,9 +290,13 @@ bool ConditionForwarding::tryOptimize(SwitchEnumInst *SEI) { llvm::SmallVector BranchArgs; unsigned HasEnumArg = NeedEnumArg.contains(SEDest); if (SEDest->getNumArguments() == 1 + HasEnumArg) { - // The successor block has an original argument, which is the Enum's - // payload. - BranchArgs.push_back(EI->getOperand()); + if (SEI->hasDefault() && SEDest == SEI->getDefaultBB()) { + BranchArgs.push_back(EI); + } else { + // The successor block has an original argument, which is the Enum's + // payload. + BranchArgs.push_back(EI->getOperand()); + } } if (HasEnumArg) { // The successor block has a new argument (which we created above) where diff --git a/test/SILOptimizer/conditionforwarding_nontrivial_ossa.sil b/test/SILOptimizer/conditionforwarding_nontrivial_ossa.sil index e62e93ab94bb4..f0ba7d9ae3e1b 100644 --- a/test/SILOptimizer/conditionforwarding_nontrivial_ossa.sil +++ b/test/SILOptimizer/conditionforwarding_nontrivial_ossa.sil @@ -21,6 +21,13 @@ enum FakeOptional { case some(T) } +enum PrimaryColor : Int { + case red = 0 + case blue = 1 + case green = 2 +} + +sil [ossa] @use_color : $@convention(thin) (PrimaryColor) -> () sil [ossa] @callee : $@convention(thin) () -> () sil [ossa] @use_enum : $@convention(thin) (@guaranteed E) -> () sil [ossa] @use_int : $@convention(thin) (Builtin.Int64) -> () @@ -134,6 +141,34 @@ bb6: return %r : $() } +sil [ossa] @simple_forwarding4 : $@convention(thin) (Builtin.Int1) -> () { +bb0(%0 : $Builtin.Int1): + cond_br %0, bb1, bb2 + +bb1: + %2 = enum $PrimaryColor, #PrimaryColor.red!enumelt + br bb3(%2 : $PrimaryColor) + +bb2: + %3 = enum $PrimaryColor, #PrimaryColor.blue!enumelt + br bb3(%3 : $PrimaryColor) + +bb3(%14 : $PrimaryColor): + switch_enum %14 : $PrimaryColor, case #PrimaryColor.red!enumelt: bb4, default bb5 + +bb4: + br bb6 + +bb5(%18 : $PrimaryColor): + %15 = function_ref @use_color : $@convention(thin) (PrimaryColor) -> () + %16 = apply %15(%18) : $@convention(thin) (PrimaryColor) -> () + br bb6 + +bb6: + %r = tuple () + return %r : $() +} + // CHECK-LABEL: sil [ossa] @simple_switch_enum_forwarding1 : // CHECK: bb0({{.*}}): // CHECK-NEXT: br bb3