Skip to content

Commit

Permalink
SILMem2Reg: fix a crash which was uncovered by the change in SROA
Browse files Browse the repository at this point in the history
It's basically fixing two over-conservative asserts.

rdar://problem/44143761
  • Loading branch information
eeckstein committed Sep 5, 2018
1 parent 72a056d commit b702f99
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
21 changes: 19 additions & 2 deletions lib/SILOptimizer/Transforms/SILMem2Reg.cpp
Expand Up @@ -203,6 +203,20 @@ static bool isAddressForLoad(SILInstruction *I, SILBasicBlock *&singleBlock) {
return true;
}

/// Returns true if \p I is a dead struct_element_addr or tuple_element_addr.
static bool isDeadAddrProjection(SILInstruction *I) {
if (!isa<StructElementAddrInst>(I) && !isa<TupleElementAddrInst>(I))
return false;

// Recursively search for uses which are dead themselves.
for (auto UI : cast<SingleValueInstruction>(I)->getUses()) {
SILInstruction *II = UI->getUser();
if (!isDeadAddrProjection(II))
return false;
}
return true;
}

/// Returns true if this AllocStacks is captured.
/// Sets \p inSingleBlock to true if all uses of \p ASI are in a single block.
static bool isCaptured(AllocStackInst *ASI, bool &inSingleBlock) {
Expand Down Expand Up @@ -266,6 +280,9 @@ bool MemoryToRegisters::isWriteOnlyAllocation(AllocStackInst *ASI) {
if (isa<DebugValueAddrInst>(II))
continue;

if (isDeadAddrProjection(II))
continue;

// Can't do anything else with it.
LLVM_DEBUG(llvm::dbgs() << "*** AllocStack has non-write use: " << *II);
return false;
Expand Down Expand Up @@ -468,8 +485,8 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *ASI) {
// with our running value.
if (isLoadFromStack(Inst, ASI)) {
if (!RunningVal) {
assert(ASI->getElementType().isVoid() &&
"Expected initialization of non-void type!");
// Loading without a previous store is only acceptable if the type is
// Void (= empty tuple) or a tuple of Voids.
RunningVal = SILUndef::get(ASI->getElementType(), ASI->getModule());
}
replaceLoad(cast<LoadInst>(Inst), RunningVal, ASI);
Expand Down
39 changes: 38 additions & 1 deletion test/SILOptimizer/mem2reg.sil
Expand Up @@ -368,7 +368,7 @@ sil @dead_use : $@convention(thin) () -> () {

// CHECK-LABEL: sil @dont_crash_on_dead_arg_use
// CHECK: bb0{{.*}}:
// CHECK-NEXT: tuple ()
// CHECK: tuple ()
// CHECK-NEXT: return
sil @dont_crash_on_dead_arg_use : $@convention(thin) (@inout Int64) -> () {
bb0(%0 : $*Int64):
Expand Down Expand Up @@ -412,3 +412,40 @@ bb0(%0 : $SmallCodesizeStruct):
%7 = tuple ()
return %7 : $()
}

// CHECK-LABEL: sil @dead_address_projections
// CHECK-NOT: alloc_stack
// CHECK: } // end sil function 'dead_address_projections'
sil @dead_address_projections : $@convention(thin) (((), ())) -> ((), ()) {
bb0(%0 : $((), ())):
%1 = alloc_stack $((), ())
%200 = tuple_element_addr %1 : $*((), ()), 0
%300 = tuple_element_addr %1 : $*((), ()), 1
cond_br undef, bb1, bb2

bb1:
store %0 to %1 : $*((), ())
%16 = load %1 : $*((), ())
dealloc_stack %1 : $*((), ())
br bb3(%16 : $((), ()))

bb2:
dealloc_stack %1 : $*((), ())
br bb3(%0 : $((), ()))

bb3(%20 : $((), ())):
return %20 : $((), ())
}

// CHECK-LABEL: sil @load_tuple_of_void
// CHECK-NOT: alloc_stack
// CHECK: return undef : $((), ())
// CHECK: } // end sil function 'load_tuple_of_void'
sil @load_tuple_of_void : $@convention(thin) () -> ((), ()) {
bb0:
%1 = alloc_stack $((), ())
%16 = load %1 : $*((), ())
dealloc_stack %1 : $*((), ())
return %16 : $((), ())
}

0 comments on commit b702f99

Please sign in to comment.