diff options
| author | John McCall <rjmccall@apple.com> | 2019-08-14 03:53:52 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2019-08-14 03:53:52 +0000 |
| commit | d47801e7182a64c52891b34e749e35c396a002f8 (patch) | |
| tree | 5c983de8fc57575529aae00f73ab26ced6b82caa /llvm/lib/Transforms | |
| parent | ac404832760a5ed71bc40083bdd52935524136c1 (diff) | |
| download | bcm5719-llvm-d47801e7182a64c52891b34e749e35c396a002f8.tar.gz bcm5719-llvm-d47801e7182a64c52891b34e749e35c396a002f8.zip | |
In coro.retcon lowering, don't explode if the optimizer messes around with the linkage of the prototype or the exact types of the yielded values.
llvm-svn: 368793
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/Coroutines.cpp | 12 |
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index 318a012b6a7..1183352271c 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -585,8 +585,25 @@ void CoroCloner::create() { SmallVector<ReturnInst *, 4> Returns; + // Ignore attempts to change certain attributes of the function. + // TODO: maybe there should be a way to suppress this during cloning? + auto savedVisibility = NewF->getVisibility(); + auto savedUnnamedAddr = NewF->getUnnamedAddr(); + auto savedDLLStorageClass = NewF->getDLLStorageClass(); + + // NewF's linkage (which CloneFunctionInto does *not* change) might not + // be compatible with the visibility of OrigF (which it *does* change), + // so protect against that. + auto savedLinkage = NewF->getLinkage(); + NewF->setLinkage(llvm::GlobalValue::ExternalLinkage); + CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns); + NewF->setLinkage(savedLinkage); + NewF->setVisibility(savedVisibility); + NewF->setUnnamedAddr(savedUnnamedAddr); + NewF->setDLLStorageClass(savedDLLStorageClass); + auto &Context = NewF->getContext(); // Replace the attributes of the new function: diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index b81a08557b4..12176570b7a 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -405,7 +405,17 @@ void coro::Shape::buildFrom(Function &F) { auto SI = Suspend->value_begin(), SE = Suspend->value_end(); auto RI = ResultTys.begin(), RE = ResultTys.end(); for (; SI != SE && RI != RE; ++SI, ++RI) { - if ((*SI)->getType() != *RI) { + auto SrcTy = (*SI)->getType(); + if (SrcTy != *RI) { + // The optimizer likes to eliminate bitcasts leading into variadic + // calls, but that messes with our invariants. Re-insert the + // bitcast and ignore this type mismatch. + if (CastInst::isBitCastable(SrcTy, *RI)) { + auto BCI = new BitCastInst(*SI, *RI, "", Suspend); + SI->set(BCI); + continue; + } + #ifndef NDEBUG Suspend->dump(); Prototype->getFunctionType()->dump(); |

