From ca093361542c7ddfa8a394146427e9f1dbf70114 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 27 Nov 2024 13:19:12 +0100 Subject: [PATCH] ConditionForwarding: fix a wrong assert Some terminator instructions can have type-dependent operands. Therefore we need to use `getNumRealOperands` instead of `getNumOperands`. Fixes a compiler crash. --- .../Transforms/ConditionForwarding.cpp | 2 +- .../SILOptimizer/conditionforwarding_ossa.sil | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/SILOptimizer/Transforms/ConditionForwarding.cpp b/lib/SILOptimizer/Transforms/ConditionForwarding.cpp index 41ceac5816162..b387772a90e0a 100644 --- a/lib/SILOptimizer/Transforms/ConditionForwarding.cpp +++ b/lib/SILOptimizer/Transforms/ConditionForwarding.cpp @@ -237,7 +237,7 @@ bool ConditionForwarding::tryOptimize(SwitchEnumInst *SEI) { if (getFunction()->hasOwnership()) { // TODO: Currently disabled because this case may need lifetime extension // Disabling this conservatively for now. - assert(Condition->getNumOperands() == 1); + assert(Condition->getNumRealOperands() == 1); BorrowedValue conditionOp(Condition->getOperand(0)); if (conditionOp && conditionOp.isLocalScope()) { return false; diff --git a/test/SILOptimizer/conditionforwarding_ossa.sil b/test/SILOptimizer/conditionforwarding_ossa.sil index 337350734572c..6914ff4e679b4 100644 --- a/test/SILOptimizer/conditionforwarding_ossa.sil +++ b/test/SILOptimizer/conditionforwarding_ossa.sil @@ -14,6 +14,8 @@ class C { init() } +final class D: C {} + sil [ossa] @callee : $@convention(thin) () -> () sil [ossa] @use_enum : $@convention(thin) (E) -> () sil [ossa] @use_int : $@convention(thin) (Builtin.Int64) -> () @@ -388,3 +390,32 @@ bb6: return %r : $() } +// CHECK-LABEL: sil [ossa] @cast_with_type_dependent_operand : +// CHECK-NOT: switch_enum +// CHECK-LABEL: } // end sil function 'cast_with_type_dependent_operand' +sil [ossa] @cast_with_type_dependent_operand : $@convention(method) (@guaranteed C, @guaranteed D) -> () { +bb0(%0 : @guaranteed $C, %1 : @guaranteed $D): + checked_cast_br C in %0 to @dynamic_self D, bb1, bb2 + +bb1(%3 : @guaranteed $D): + %4 = enum $Optional, #Optional.some!enumelt, %3 + br bb3(%4) + +bb2(%6 : @guaranteed $C): + %7 = enum $Optional, #Optional.none!enumelt + br bb3(%7) + +bb3(%9 : @guaranteed $Optional): + %10 = borrowed %9 from (%0) + switch_enum %10, case #Optional.some!enumelt: bb4, case #Optional.none!enumelt: bb5 + +bb4(%12 : @guaranteed $D): + br bb6 + +bb5: + br bb6 + +bb6: + %15 = tuple () + return %15 +}