diff options
| author | Eugene Leviant <eleviant@accesssoftek.com> | 2018-06-22 08:29:36 +0000 |
|---|---|---|
| committer | Eugene Leviant <eleviant@accesssoftek.com> | 2018-06-22 08:29:36 +0000 |
| commit | ea19c9473c4237c598e8a773f84fdeb695724a63 (patch) | |
| tree | b514c4038427cc5759a4f6ef1ef827c217387c67 /llvm/lib/Transforms | |
| parent | 09635620836c4fb88cee21df15af77d6427fc3ac (diff) | |
| download | bcm5719-llvm-ea19c9473c4237c598e8a773f84fdeb695724a63.tar.gz bcm5719-llvm-ea19c9473c4237c598e8a773f84fdeb695724a63.zip | |
[Evaluator] Improve evaluation of call instruction
Differential revision: https://reviews.llvm.org/D46584
llvm-svn: 335324
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Utils/Evaluator.cpp | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index 9440ae3ef2a..3f9daa2d29a 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -217,6 +217,33 @@ Constant *Evaluator::ComputeLoadResult(Constant *P) { return nullptr; // don't know how to evaluate. } +Function *Evaluator::getCallee(Value *V) { + auto *CE = dyn_cast<ConstantExpr>(V); + if (!CE) + return dyn_cast<Function>(getVal(V)); + + Constant *C = + CE->getOpcode() == Instruction::BitCast + ? ConstantFoldLoadThroughBitcast(CE, CE->getOperand(0)->getType(), DL) + : CE; + return dyn_cast<Function>(C); +} + +/// If call expression contains bitcast then we may need to cast +/// evaluated return value to a type of the call expression. +Constant *Evaluator::castCallResultIfNeeded(Value *CallExpr, Constant *RV) { + ConstantExpr *CE = dyn_cast<ConstantExpr>(CallExpr); + if (!CE || CE->getOpcode() != Instruction::BitCast) + return RV; + + if (auto *FT = + dyn_cast<FunctionType>(CE->getType()->getPointerElementType())) { + RV = ConstantFoldLoadThroughBitcast(RV, FT->getReturnType(), DL); + assert(RV && "Failed to fold bitcast call expr"); + } + return RV; +} + /// Evaluate all instructions in block BB, returning true if successful, false /// if we can't evaluate it. NewBB returns the next BB that control flows into, /// or null upon return. @@ -465,7 +492,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, } // Resolve function pointers. - Function *Callee = dyn_cast<Function>(getVal(CS.getCalledValue())); + Function *Callee = getCallee(CS.getCalledValue()); if (!Callee || Callee->isInterposable()) { LLVM_DEBUG(dbgs() << "Can not resolve function pointer.\n"); return false; // Cannot resolve. @@ -478,7 +505,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, if (Callee->isDeclaration()) { // If this is a function we can constant fold, do it. if (Constant *C = ConstantFoldCall(CS, Callee, Formals, TLI)) { - InstResult = C; + InstResult = castCallResultIfNeeded(CS.getCalledValue(), C); LLVM_DEBUG(dbgs() << "Constant folded function call. Result: " << *InstResult << "\n"); } else { @@ -499,7 +526,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, return false; } ValueStack.pop_back(); - InstResult = RetVal; + InstResult = castCallResultIfNeeded(CS.getCalledValue(), RetVal); if (InstResult) { LLVM_DEBUG(dbgs() << "Successfully evaluated function. Result: " |

