summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2018-12-07 03:01:54 +0000
committerVedant Kumar <vsk@apple.com>2018-12-07 03:01:54 +0000
commitb2a6f8e505b105c733d931e1ed0513d7ea94f6c8 (patch)
tree1e58c4acf583de190493ad34ec95af79996ae95a /llvm/lib/Transforms/Utils
parent5fa736cc193968d59286e94b8b49e983d9e72384 (diff)
downloadbcm5719-llvm-b2a6f8e505b105c733d931e1ed0513d7ea94f6c8.tar.gz
bcm5719-llvm-b2a6f8e505b105c733d931e1ed0513d7ea94f6c8.zip
[CodeExtractor] Store outputs at the first valid insertion point
When CodeExtractor outlines values which are used by the original function, it must store those values in some in-out parameter. This store instruction must not be inserted in between a PHI and an EH pad instruction, as that results in invalid IR. This fixes the following verifier failure seen while outlining within ObjC methods with live exit values: The unwind destination does not have an exception handling instruction! %call35 = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %exn.adjusted, i8* %1) to label %invoke.cont34 unwind label %lpad33, !dbg !4183 The unwind destination does not have an exception handling instruction! invoke void @objc_exception_throw(i8* %call35) #12 to label %invoke.cont36 unwind label %lpad33, !dbg !4184 LandingPadInst not the first non-PHI instruction in the block. %3 = landingpad { i8*, i32 } catch i8* null, !dbg !1411 rdar://46540815 llvm-svn: 348562
Diffstat (limited to 'llvm/lib/Transforms/Utils')
-rw-r--r--llvm/lib/Transforms/Utils/CodeExtractor.cpp24
1 files changed, 12 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index dbcee9e5755..a6b01107752 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -992,17 +992,15 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer,
continue;
// Find proper insertion point.
- Instruction *InsertPt;
+ BasicBlock::iterator InsertPt;
// In case OutI is an invoke, we insert the store at the beginning in the
// 'normal destination' BB. Otherwise we insert the store right after OutI.
if (auto *InvokeI = dyn_cast<InvokeInst>(OutI))
- InsertPt = InvokeI->getNormalDest()->getFirstNonPHI();
+ InsertPt = InvokeI->getNormalDest()->getFirstInsertionPt();
+ else if (auto *Phi = dyn_cast<PHINode>(OutI))
+ InsertPt = Phi->getParent()->getFirstInsertionPt();
else
- InsertPt = OutI->getNextNode();
-
- // Let's assume that there is no other guy interleave non-PHI in PHIs.
- if (isa<PHINode>(InsertPt))
- InsertPt = InsertPt->getParent()->getFirstNonPHI();
+ InsertPt = std::next(OutI->getIterator());
assert(OAI != newFunction->arg_end() &&
"Number of output arguments should match "
@@ -1012,13 +1010,13 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer,
Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context));
Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), FirstOut + i);
GetElementPtrInst *GEP = GetElementPtrInst::Create(
- StructArgTy, &*OAI, Idx, "gep_" + outputs[i]->getName(), InsertPt);
- new StoreInst(outputs[i], GEP, InsertPt);
+ StructArgTy, &*OAI, Idx, "gep_" + outputs[i]->getName(), &*InsertPt);
+ new StoreInst(outputs[i], GEP, &*InsertPt);
// Since there should be only one struct argument aggregating
// all the output values, we shouldn't increment OAI, which always
// points to the struct argument, in this case.
} else {
- new StoreInst(outputs[i], &*OAI, InsertPt);
+ new StoreInst(outputs[i], &*OAI, &*InsertPt);
++OAI;
}
}
@@ -1379,8 +1377,10 @@ Function *CodeExtractor::extractCodeRegion() {
if (doesNotReturn)
newFunction->setDoesNotReturn();
- LLVM_DEBUG(if (verifyFunction(*newFunction))
- report_fatal_error("verification of newFunction failed!"));
+ LLVM_DEBUG(if (verifyFunction(*newFunction, &errs())) {
+ newFunction->dump();
+ report_fatal_error("verification of newFunction failed!");
+ });
LLVM_DEBUG(if (verifyFunction(*oldFunction))
report_fatal_error("verification of oldFunction failed!"));
return newFunction;
OpenPOWER on IntegriCloud