summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-13 01:15:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-13 01:15:46 +0000
commit25a796e148887e50c743b9aa93765e8c5f1f1faa (patch)
treed816924ed2e92f9392db054fb12a309d877d8686 /llvm/lib/Analysis
parent9262da26d05018565f9d6c09d5788ce8a66ea08c (diff)
downloadbcm5719-llvm-25a796e148887e50c743b9aa93765e8c5f1f1faa.tar.gz
bcm5719-llvm-25a796e148887e50c743b9aa93765e8c5f1f1faa.zip
[InstSimplify] Teach InstSimplify how to simplify extractvalue
llvm-svn: 242007
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index ab5cd01ab63..ad85a3ed73c 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3520,6 +3520,41 @@ Value *llvm::SimplifyInsertValueInst(
RecursionLimit);
}
+/// SimplifyExtractValueInst - Given operands for an ExtractValueInst, see if we
+/// can fold the result. If not, this returns null.
+static Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const Query &, unsigned) {
+ if (auto *CAgg = dyn_cast<Constant>(Agg))
+ return ConstantFoldExtractValueInstruction(CAgg, Idxs);
+
+ // extractvalue x, (insertvalue y, elt, n), n -> elt
+ unsigned NumIdxs = Idxs.size();
+ for (auto *IVI = dyn_cast<InsertValueInst>(Agg); IVI != nullptr;
+ IVI = dyn_cast<InsertValueInst>(IVI->getAggregateOperand())) {
+ ArrayRef<unsigned> InsertValueIdxs = IVI->getIndices();
+ unsigned NumInsertValueIdxs = InsertValueIdxs.size();
+ unsigned NumCommonIdxs = std::min(NumInsertValueIdxs, NumIdxs);
+ if (InsertValueIdxs.slice(0, NumCommonIdxs) ==
+ Idxs.slice(0, NumCommonIdxs)) {
+ if (NumIdxs == NumInsertValueIdxs)
+ return IVI->getInsertedValueOperand();
+ break;
+ }
+ }
+
+ return nullptr;
+}
+
+Value *llvm::SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI,
+ const DominatorTree *DT,
+ AssumptionCache *AC,
+ const Instruction *CxtI) {
+ return ::SimplifyExtractValueInst(Agg, Idxs, Query(DL, TLI, DT, AC, CxtI),
+ RecursionLimit);
+}
+
/// SimplifyPHINode - See if we can fold the given phi. If not, returns null.
static Value *SimplifyPHINode(PHINode *PN, const Query &Q) {
// If all of the PHI's incoming values are the same then replace the PHI node
@@ -3929,6 +3964,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
IV->getIndices(), DL, TLI, DT, AC, I);
break;
}
+ case Instruction::ExtractValue: {
+ auto *EVI = cast<ExtractValueInst>(I);
+ Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
+ EVI->getIndices(), DL, TLI, DT, AC, I);
+ break;
+ }
case Instruction::PHI:
Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I));
break;
OpenPOWER on IntegriCloud