[llvm] r368793 - 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.
John McCall via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 20:53:52 PDT 2019
Author: rjmccall
Date: Tue Aug 13 20:53:52 2019
New Revision: 368793
URL: http://llvm.org/viewvc/llvm-project?rev=368793&view=rev
Log:
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.
Modified:
llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp
llvm/trunk/lib/Transforms/Coroutines/Coroutines.cpp
llvm/trunk/test/Transforms/Coroutines/coro-retcon.ll
Modified: llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp?rev=368793&r1=368792&r2=368793&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp (original)
+++ llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp Tue Aug 13 20:53:52 2019
@@ -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:
Modified: llvm/trunk/lib/Transforms/Coroutines/Coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Coroutines/Coroutines.cpp?rev=368793&r1=368792&r2=368793&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Coroutines/Coroutines.cpp (original)
+++ llvm/trunk/lib/Transforms/Coroutines/Coroutines.cpp Tue Aug 13 20:53:52 2019
@@ -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();
Modified: llvm/trunk/test/Transforms/Coroutines/coro-retcon.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Coroutines/coro-retcon.ll?rev=368793&r1=368792&r2=368793&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Coroutines/coro-retcon.ll (original)
+++ llvm/trunk/test/Transforms/Coroutines/coro-retcon.ll Tue Aug 13 20:53:52 2019
@@ -78,6 +78,25 @@ entry:
; CHECK-NEXT: call void @print(i32 [[INC]])
; CHECK-NEXT: ret i32 0
+define hidden { i8*, i8* } @g(i8* %buffer, i16* %ptr) {
+entry:
+ %id = call token @llvm.coro.id.retcon(i32 8, i32 4, i8* %buffer, i8* bitcast ({ i8*, i8* } (i8*, i1)* @g_prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
+ %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
+ br label %loop
+
+loop:
+ %ptr2 = bitcast i16* %ptr to i8*
+ %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(i8* %ptr2)
+ br i1 %unwind0, label %cleanup, label %resume
+
+resume:
+ br label %loop
+
+cleanup:
+ call i1 @llvm.coro.end(i8* %hdl, i1 0)
+ unreachable
+}
+
declare token @llvm.coro.id.retcon(i32, i32, i8*, i8*, i8*, i8*)
declare i8* @llvm.coro.begin(token, i8*)
declare i1 @llvm.coro.suspend.retcon.i1(...)
@@ -85,6 +104,7 @@ declare i1 @llvm.coro.end(i8*, i1)
declare i8* @llvm.coro.prepare.retcon(i8*)
declare i8* @prototype(i8*, i1 zeroext)
+declare {i8*,i8*} @g_prototype(i8*, i1 zeroext)
declare noalias i8* @allocate(i32 %size)
declare void @deallocate(i8* %ptr)
More information about the llvm-commits
mailing list