diff options
author | Brian Gesiak <modocache@gmail.com> | 2018-02-15 19:31:45 +0000 |
---|---|---|
committer | Brian Gesiak <modocache@gmail.com> | 2018-02-15 19:31:45 +0000 |
commit | a5e3675bd3bb333257191a0dc37c59e41b418823 (patch) | |
tree | 08c3ab795fe731a2847797dcf146260758586fdf /llvm/lib/Transforms/Coroutines | |
parent | 60f5aabc64ee900a37edf7510d3ca3bb88d3ea1c (diff) | |
download | bcm5719-llvm-a5e3675bd3bb333257191a0dc37c59e41b418823.tar.gz bcm5719-llvm-a5e3675bd3bb333257191a0dc37c59e41b418823.zip |
[Coroutines] Don't move stores for allocator args
Summary:
The behavior described in Coroutines TS `[dcl.fct.def.coroutine]/7`
allows coroutine parameters to be passed into allocator functions.
The instructions to store values into the alloca'd parameters must not
be moved past the frame allocation, otherwise uninitialized values are
passed to the allocator.
Test Plan: `check-llvm`
Reviewers: rsmith, GorNishanov, eric_niebler
Reviewed By: GorNishanov
Subscribers: compnerd, EricWF, llvm-commits
Differential Revision: https://reviews.llvm.org/D43000
llvm-svn: 325285
Diffstat (limited to 'llvm/lib/Transforms/Coroutines')
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 4a69fbfe435..28c291696ab 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -654,13 +654,28 @@ getNotRelocatableInstructions(CoroBeginInst *CoroBegin, // set. do { Instruction *Current = Work.pop_back_val(); + DEBUG(dbgs() << "CoroSplit: Will not relocate: " << *Current << "\n"); DoNotRelocate.insert(Current); for (Value *U : Current->operands()) { auto *I = dyn_cast<Instruction>(U); if (!I) continue; - if (isa<AllocaInst>(U)) + + if (auto *A = dyn_cast<AllocaInst>(I)) { + // Stores to alloca instructions that occur before the coroutine frame + // is allocated should not be moved; the stored values may be used by + // the coroutine frame allocator. The operands to those stores must also + // remain in place. + for (const auto &User : A->users()) + if (auto *SI = dyn_cast<llvm::StoreInst>(User)) + if (RelocBlocks.count(SI->getParent()) != 0 && + DoNotRelocate.count(SI) == 0) { + Work.push_back(SI); + DoNotRelocate.insert(SI); + } continue; + } + if (DoNotRelocate.count(I) == 0) { Work.push_back(I); DoNotRelocate.insert(I); |