diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp index 7935b0727a833..99eb4e224788e 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp @@ -2145,8 +2145,13 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { Builder.setCurrentDebugScope(ARDI->getDebugScope()); SILValue MDVal = ARDI->getMetatypeOperand(); - while (auto *UCI = dyn_cast(MDVal)) + while (auto *UCI = dyn_cast(MDVal)) { + // For simplicity ignore a cast of an `alloc_ref [stack]`. It would need more + // work to keep its `dealloc_stack_ref` correct. + if (ARDI->canAllocOnStack()) + return nullptr; MDVal = UCI->getOperand(); + } SingleValueInstruction *NewInst = nullptr; if (auto *MI = dyn_cast(MDVal)) { @@ -2159,7 +2164,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { return nullptr; NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy, - ARDI->isObjC(), false, + ARDI->isObjC(), ARDI->canAllocOnStack(), ARDI->getTailAllocatedTypes(), getCounts(ARDI)); @@ -2184,11 +2189,14 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { if (!SILInstanceTy.getClassOrBoundGenericClass()) return nullptr; NewInst = Builder.createAllocRef(ARDI->getLoc(), SILInstanceTy, - ARDI->isObjC(), false, + ARDI->isObjC(), ARDI->canAllocOnStack(), ARDI->getTailAllocatedTypes(), getCounts(ARDI)); } } else if (auto *AI = dyn_cast(MDVal)) { + if (ARDI->canAllocOnStack()) + return nullptr; + SILFunction *SF = AI->getReferencedFunctionOrNull(); if (!SF) return nullptr; @@ -2217,6 +2225,7 @@ visitAllocRefDynamicInst(AllocRefDynamicInst *ARDI) { if (NewInst && NewInst->getType() != ARDI->getType()) { // In case the argument was an upcast of the metatype, we have to upcast the // resulting reference. + assert(!ARDI->canAllocOnStack() && "upcasting alloc_ref [stack] not supported"); NewInst = Builder.createUpcast(ARDI->getLoc(), NewInst, ARDI->getType()); } return NewInst; diff --git a/test/SILOptimizer/sil_combine_ossa.sil b/test/SILOptimizer/sil_combine_ossa.sil index 74c5fdbd165c0..1cbdc34568e22 100644 --- a/test/SILOptimizer/sil_combine_ossa.sil +++ b/test/SILOptimizer/sil_combine_ossa.sil @@ -3149,6 +3149,61 @@ bb3 (%10: $Builtin.Int32): return %10 : $Builtin.Int32 } +// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_metatype : +// CHECK: bb0: +// CHECK-NOT: alloc_ref_dynamic +// CHECK-NEXT: alloc_ref [stack] $B +// CHECK-NEXT: destroy_value +// CHECK-NEXT: dealloc_stack_ref +// CHECK: return +// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_metatype' +sil [ossa] @alloc_ref_dynamic_stack_with_metatype : $() -> () { + %1 = metatype $@thick B.Type + %2 = alloc_ref_dynamic [stack] %1 : $@thick B.Type, $B + destroy_value %2 : $B + dealloc_stack_ref %2 : $B + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype : +// CHECK: alloc_ref_dynamic [stack] +// CHECK: } // end sil function 'alloc_ref_dynamic_stack_with_upcast_metatype' +sil [ossa] @alloc_ref_dynamic_stack_with_upcast_metatype : $() -> () { + %1 = metatype $@thick E.Type + %2 = upcast %1 : $@thick E.Type to $@thick B.Type + %3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B + destroy_value %3 : $B + dealloc_stack_ref %3 : $B + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: @alloc_ref_dynamic_stack_after_successful_checked_cast_br : +// CHECK: checked_cast_br +// CHECK: bb1 +// CHECK-NOT: alloc_ref_dynamic +// CHECK: alloc_ref [stack] $B +// CHECK: } // end sil function 'alloc_ref_dynamic_stack_after_successful_checked_cast_br' +sil [ossa] @alloc_ref_dynamic_stack_after_successful_checked_cast_br : $(@thick B.Type) -> Builtin.Int32 { +bb0(%1 : $@thick B.Type): + checked_cast_br [exact] %1 : $@thick B.Type to B.Type, bb1, bb2 + +bb1(%2 : $@thick B.Type): + %3 = alloc_ref_dynamic [stack] %2 : $@thick B.Type, $B + destroy_value %3 : $B + dealloc_stack_ref %3 : $B + %4 = integer_literal $Builtin.Int32, 1 + br bb3 (%4 : $Builtin.Int32) + +bb2(%2a : $@thick B.Type): + %5 = integer_literal $Builtin.Int32, 2 + br bb3 (%5 : $Builtin.Int32) + +bb3 (%10: $Builtin.Int32): + return %10 : $Builtin.Int32 +} + // CHECK-LABEL: sil [ossa] @delete_dead_alloc_stack // XHECK: bb0 // XHECK-NEXT: tuple