summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2019-08-14 03:53:52 +0000
committerJohn McCall <rjmccall@apple.com>2019-08-14 03:53:52 +0000
commitd47801e7182a64c52891b34e749e35c396a002f8 (patch)
tree5c983de8fc57575529aae00f73ab26ced6b82caa /llvm/lib/Transforms
parentac404832760a5ed71bc40083bdd52935524136c1 (diff)
downloadbcm5719-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.cpp17
-rw-r--r--llvm/lib/Transforms/Coroutines/Coroutines.cpp12
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();
OpenPOWER on IntegriCloud