Skip to content

Commit 70d3c34

Browse files
committed
[5.0] Don't duplicate basic blocks ending in dynamic_method_br
IRGen does not support objc methods thunks. * No ABI impact * Fixes a compiler crash rdar://46531828
1 parent d0a4978 commit 70d3c34

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

lib/SIL/LoopInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ bool SILLoop::canDuplicate(SILInstruction *I) const {
9898
if (isa<BeginAccessInst>(I))
9999
return false;
100100

101+
if (isa<DynamicMethodBranchInst>(I))
102+
return false;
103+
101104
assert(I->isTriviallyDuplicatable() &&
102105
"Code here must match isTriviallyDuplicatable in SILInstruction");
103106
return true;

lib/SIL/SILInstruction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,11 @@ bool SILInstruction::isTriviallyDuplicatable() const {
11821182
if (isa<BeginApplyInst>(this))
11831183
return false;
11841184

1185+
// dynamic_method_br is not duplicatable because IRGen does not support phi
1186+
// nodes of objc_method type.
1187+
if (isa<DynamicMethodBranchInst>(this))
1188+
return false;
1189+
11851190
// If you add more cases here, you should also update SILLoop:canDuplicate.
11861191

11871192
return true;

lib/SIL/SILVerifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
40464046
require(!(isa<MethodInst>(branchArg) &&
40474047
cast<MethodInst>(branchArg)->getMember().isForeign),
40484048
"branch argument cannot be a witness_method or an objc method_inst");
4049+
require(!(branchArg->getType().is<SILFunctionType>() &&
4050+
branchArg->getType()
4051+
.castTo<SILFunctionType>()
4052+
->getExtInfo()
4053+
.getRepresentation() ==
4054+
SILFunctionTypeRepresentation::ObjCMethod),
4055+
"branch argument cannot be a objective-c method");
40494056
return branchArg->getType() == bbArg->getType();
40504057
}
40514058

test/SILOptimizer/simplify_cfg.sil

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,3 +3147,46 @@ bb6:
31473147
%rv = tuple ()
31483148
return %rv : $()
31493149
}
3150+
3151+
class X {
3152+
@objc func f() { }
3153+
}
3154+
3155+
sil @external_g : $@convention(thin) () -> ()
3156+
3157+
// Don't tail duplicate dynamic_method_br. IRGen cannot handle phi nodes of
3158+
// objc_methods.
3159+
// CHECK-LABEL: sil @dont_tail_duplicate_dynamic_method_br
3160+
// CHECK: dynamic_method_br
3161+
// CHECK-NOT: dynamic_method_br
3162+
// CHECK: return
3163+
sil @dont_tail_duplicate_dynamic_method_br : $@convention(thin) (@owned Builtin.UnknownObject, Builtin.Int1) -> () {
3164+
bb0(%x : $Builtin.UnknownObject, %b : $Builtin.Int1):
3165+
cond_br %b, bb1, bb2
3166+
3167+
bb1:
3168+
%f = function_ref @external_f : $@convention(thin) () -> ()
3169+
apply %f() : $@convention(thin) () -> ()
3170+
strong_retain %x : $Builtin.UnknownObject
3171+
br bb3(%x : $Builtin.UnknownObject)
3172+
3173+
bb2:
3174+
%g = function_ref @external_g : $@convention(thin) () -> ()
3175+
apply %g() : $@convention(thin) () -> ()
3176+
strong_retain %x : $Builtin.UnknownObject
3177+
br bb3(%x : $Builtin.UnknownObject)
3178+
3179+
bb3(%y: $Builtin.UnknownObject):
3180+
strong_release %y : $Builtin.UnknownObject
3181+
dynamic_method_br %x : $Builtin.UnknownObject, #X.f!1.foreign, bb4, bb5
3182+
3183+
bb4(%m : $@convention(objc_method) (Builtin.UnknownObject) -> ()):
3184+
br bb6
3185+
3186+
bb5:
3187+
br bb6
3188+
3189+
bb6:
3190+
%r = tuple()
3191+
return %r : $()
3192+
}

0 commit comments

Comments
 (0)