Skip to content

Commit 04c6ff7

Browse files
committed
SILCombine: correctly set the [stack] flag when replacing alloc_ref_dynamic with alloc_ref
Fixes a verifier crash. #66312
1 parent c9d20c4 commit 04c6ff7

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,8 +1761,13 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
17611761
Builder.setCurrentDebugScope(ARDI->getDebugScope());
17621762

17631763
SILValue MDVal = ARDI->getMetatypeOperand();
1764-
while (auto *UCI = dyn_cast<UpcastInst>(MDVal))
1764+
while (auto *UCI = dyn_cast<UpcastInst>(MDVal)) {
1765+
// For simplicity ignore a cast of an `alloc_ref [stack]`. It would need
1766+
// to keep it's `dealloc_stack_ref` correct.
1767+
if (ARDI->canAllocOnStack())
1768+
return nullptr;
17651769
MDVal = UCI->getOperand();
1770+
}
17661771

17671772
SingleValueInstruction *NewInst = nullptr;
17681773
if (auto *MI = dyn_cast<MetatypeInst>(MDVal)) {
@@ -1775,7 +1780,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
17751780
return nullptr;
17761781

17771782
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
1778-
ARDI->isObjC(), false,
1783+
ARDI->isObjC(), ARDI->canAllocOnStack(),
17791784
ARDI->getTailAllocatedTypes(),
17801785
getCounts(ARDI));
17811786

@@ -1800,11 +1805,14 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
18001805
if (!SILInstanceTy.getClassOrBoundGenericClass())
18011806
return nullptr;
18021807
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
1803-
ARDI->isObjC(), false,
1808+
ARDI->isObjC(), ARDI->canAllocOnStack(),
18041809
ARDI->getTailAllocatedTypes(),
18051810
getCounts(ARDI));
18061811
}
18071812
} else if (auto *AI = dyn_cast<ApplyInst>(MDVal)) {
1813+
if (ARDI->canAllocOnStack())
1814+
return nullptr;
1815+
18081816
SILFunction *SF = AI->getReferencedFunctionOrNull();
18091817
if (!SF)
18101818
return nullptr;
@@ -1833,6 +1841,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
18331841
if (NewInst && NewInst->getType() != ARDI->getType()) {
18341842
// In case the argument was an upcast of the metatype, we have to upcast the
18351843
// resulting reference.
1844+
assert(!ARDI->canAllocOnStack() && "upcasting alloc_ref [stack] not supported");
18361845
NewInst = Builder.createUpcast(ARDI->getLoc(), NewInst, ARDI->getType());
18371846
}
18381847
return NewInst;

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,6 +3119,61 @@ bb3 (%10: $Builtin.Int32):
31193119
return %10 : $Builtin.Int32
31203120
}
31213121

3122+
// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_metatype :
3123+
// CHECK: bb0:
3124+
// CHECK-NOT: alloc_ref_dynamic
3125+
// CHECK-NEXT: alloc_ref [stack] $B
3126+
// CHECK-NEXT: destroy_value
3127+
// CHECK-NEXT: dealloc_stack_ref
3128+
// CHECK: return
3129+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_metatype'
3130+
sil [ossa] @alloc_ref_dynamic_stack_with_metatype : $() -> () {
3131+
%1 = metatype $@thick B.Type
3132+
%2 = alloc_ref_dynamic [stack] %1 : $@thick B.Type, $B
3133+
destroy_value %2 : $B
3134+
dealloc_stack_ref %2 : $B
3135+
%4 = tuple()
3136+
return %4 : $()
3137+
}
3138+
3139+
// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype :
3140+
// CHECK: alloc_ref_dynamic [stack]
3141+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_upcast_metatype'
3142+
sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype : $() -> () {
3143+
%1 = metatype $@thick E.Type
3144+
%2 = upcast %1 : $@thick E.Type to $@thick B.Type
3145+
%3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B
3146+
destroy_value %3 : $B
3147+
dealloc_stack_ref %3 : $B
3148+
%4 = tuple()
3149+
return %4 : $()
3150+
}
3151+
3152+
// CHECK-LABEL: @alloc_ref_dynamic_stack_after_successful_checked_cast_br :
3153+
// CHECK: checked_cast_br
3154+
// CHECK: bb1
3155+
// CHECK-NOT: alloc_ref_dynamic
3156+
// CHECK: alloc_ref [stack] $B
3157+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_after_successful_checked_cast_br'
3158+
sil [ossa] @alloc_ref_dynamic_stack_after_successful_checked_cast_br : $(@thick B.Type) -> Builtin.Int32 {
3159+
bb0(%1 : $@thick B.Type):
3160+
checked_cast_br [exact] %1 : $@thick B.Type to B.Type, bb1, bb2
3161+
3162+
bb1(%2 : $@thick B.Type):
3163+
%3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B
3164+
destroy_value %3 : $B
3165+
dealloc_stack_ref %3 : $B
3166+
%4 = integer_literal $Builtin.Int32, 1
3167+
br bb3 (%4 : $Builtin.Int32)
3168+
3169+
bb2(%2a : $@thick B.Type):
3170+
%5 = integer_literal $Builtin.Int32, 2
3171+
br bb3 (%5 : $Builtin.Int32)
3172+
3173+
bb3 (%10: $Builtin.Int32):
3174+
return %10 : $Builtin.Int32
3175+
}
3176+
31223177
// CHECK-LABEL: sil [ossa] @delete_dead_alloc_stack
31233178
// XHECK: bb0
31243179
// XHECK-NEXT: tuple

0 commit comments

Comments
 (0)