Skip to content

Commit e018d48

Browse files
authored
Merge pull request #66816 from eeckstein/fix-allocref-combine-5.9
[5.9] SILCombine: correctly set the `[stack]` flag when replacing `alloc_ref_dynamic` with `alloc_ref`
2 parents 9989e6c + 86a101f commit e018d48

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
@@ -2145,8 +2145,13 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
21452145
Builder.setCurrentDebugScope(ARDI->getDebugScope());
21462146

21472147
SILValue MDVal = ARDI->getMetatypeOperand();
2148-
while (auto *UCI = dyn_cast<UpcastInst>(MDVal))
2148+
while (auto *UCI = dyn_cast<UpcastInst>(MDVal)) {
2149+
// For simplicity ignore a cast of an `alloc_ref [stack]`. It would need more
2150+
// work to keep its `dealloc_stack_ref` correct.
2151+
if (ARDI->canAllocOnStack())
2152+
return nullptr;
21492153
MDVal = UCI->getOperand();
2154+
}
21502155

21512156
SingleValueInstruction *NewInst = nullptr;
21522157
if (auto *MI = dyn_cast<MetatypeInst>(MDVal)) {
@@ -2159,7 +2164,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
21592164
return nullptr;
21602165

21612166
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
2162-
ARDI->isObjC(), false,
2167+
ARDI->isObjC(), ARDI->canAllocOnStack(),
21632168
ARDI->getTailAllocatedTypes(),
21642169
getCounts(ARDI));
21652170

@@ -2184,11 +2189,14 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
21842189
if (!SILInstanceTy.getClassOrBoundGenericClass())
21852190
return nullptr;
21862191
NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy,
2187-
ARDI->isObjC(), false,
2192+
ARDI->isObjC(), ARDI->canAllocOnStack(),
21882193
ARDI->getTailAllocatedTypes(),
21892194
getCounts(ARDI));
21902195
}
21912196
} else if (auto *AI = dyn_cast<ApplyInst>(MDVal)) {
2197+
if (ARDI->canAllocOnStack())
2198+
return nullptr;
2199+
21922200
SILFunction *SF = AI->getReferencedFunctionOrNull();
21932201
if (!SF)
21942202
return nullptr;
@@ -2217,6 +2225,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) {
22172225
if (NewInst && NewInst->getType() != ARDI->getType()) {
22182226
// In case the argument was an upcast of the metatype, we have to upcast the
22192227
// resulting reference.
2228+
assert(!ARDI->canAllocOnStack() && "upcasting alloc_ref [stack] not supported");
22202229
NewInst = Builder.createUpcast(ARDI->getLoc(), NewInst, ARDI->getType());
22212230
}
22222231
return NewInst;

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3149,6 +3149,61 @@ bb3 (%10: $Builtin.Int32):
31493149
return %10 : $Builtin.Int32
31503150
}
31513151

3152+
// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_metatype :
3153+
// CHECK: bb0:
3154+
// CHECK-NOT: alloc_ref_dynamic
3155+
// CHECK-NEXT: alloc_ref [stack] $B
3156+
// CHECK-NEXT: destroy_value
3157+
// CHECK-NEXT: dealloc_stack_ref
3158+
// CHECK: return
3159+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_metatype'
3160+
sil [ossa] @alloc_ref_dynamic_stack_with_metatype : $() -> () {
3161+
%1 = metatype $@thick B.Type
3162+
%2 = alloc_ref_dynamic [stack] %1 : $@thick B.Type, $B
3163+
destroy_value %2 : $B
3164+
dealloc_stack_ref %2 : $B
3165+
%4 = tuple()
3166+
return %4 : $()
3167+
}
3168+
3169+
// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype :
3170+
// CHECK: alloc_ref_dynamic [stack]
3171+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_upcast_metatype'
3172+
sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype : $() -> () {
3173+
%1 = metatype $@thick E.Type
3174+
%2 = upcast %1 : $@thick E.Type to $@thick B.Type
3175+
%3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B
3176+
destroy_value %3 : $B
3177+
dealloc_stack_ref %3 : $B
3178+
%4 = tuple()
3179+
return %4 : $()
3180+
}
3181+
3182+
// CHECK-LABEL: @alloc_ref_dynamic_stack_after_successful_checked_cast_br :
3183+
// CHECK: checked_cast_br
3184+
// CHECK: bb1
3185+
// CHECK-NOT: alloc_ref_dynamic
3186+
// CHECK: alloc_ref [stack] $B
3187+
// CHECK: } // end sil function 'alloc_ref_dynamic_stack_after_successful_checked_cast_br'
3188+
sil [ossa] @alloc_ref_dynamic_stack_after_successful_checked_cast_br : $(@thick B.Type) -> Builtin.Int32 {
3189+
bb0(%1 : $@thick B.Type):
3190+
checked_cast_br [exact] %1 : $@thick B.Type to B.Type, bb1, bb2
3191+
3192+
bb1(%2 : $@thick B.Type):
3193+
%3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B
3194+
destroy_value %3 : $B
3195+
dealloc_stack_ref %3 : $B
3196+
%4 = integer_literal $Builtin.Int32, 1
3197+
br bb3 (%4 : $Builtin.Int32)
3198+
3199+
bb2(%2a : $@thick B.Type):
3200+
%5 = integer_literal $Builtin.Int32, 2
3201+
br bb3 (%5 : $Builtin.Int32)
3202+
3203+
bb3 (%10: $Builtin.Int32):
3204+
return %10 : $Builtin.Int32
3205+
}
3206+
31523207
// CHECK-LABEL: sil [ossa] @delete_dead_alloc_stack
31533208
// XHECK: bb0
31543209
// XHECK-NEXT: tuple

0 commit comments

Comments
 (0)