Hack to workaround a clang lto bug

We hit an assert in AllocStackHoisting that is only triggered in a release lto
build.

Clang forwards the read of parent basic block of 'AssignedLoc' in the next
statement:

  auto *EntryBB = AssignedLoc->getFunction()->getEntryBlock(); // read AssignedLoc->ParentBB
  AssignedLoc->removeFromParent(); // writes AssignedLoc->ParentBB

To this read:

  EntryBB->push_front(AssignedLoc); // read AssignedLoc->ParentBB and assert if non-null, *should reload*

As a temporary workaround outline code to prevent the miscompile.

rdar://29982182
This commit is contained in:
Arnold Schwaighofer
2017-01-12 19:45:46 -08:00
parent 8caa0e6ca2
commit d6dd8e83bc

View File

@@ -110,6 +110,13 @@ insertDeallocStackAtEndOf(SmallVectorImpl<SILInstruction *> &FunctionExits,
}
}
/// Hack to workaround a clang LTO bug.
__attribute__((noinline))
void moveAllocStackToBeginningOfBlock(AllocStackInst* AS, SILBasicBlock *BB) {
AS->removeFromParent();
BB->push_front(AS);
}
/// Assign a single alloc_stack instruction to all the alloc_stacks in the
/// partition.
void Partition::assignStackLocation(
@@ -120,8 +127,7 @@ void Partition::assignStackLocation(
// Move this assigned location to the beginning of the entry block.
auto *EntryBB = AssignedLoc->getFunction()->getEntryBlock();
AssignedLoc->removeFromParent();
EntryBB->push_front(AssignedLoc);
moveAllocStackToBeginningOfBlock(AssignedLoc, EntryBB);
// Erase the dealloc_stacks.
eraseDeallocStacks(AssignedLoc);