diff options
author | Zvi Rackover <zvi.rackover@intel.com> | 2017-04-03 22:05:30 +0000 |
---|---|---|
committer | Zvi Rackover <zvi.rackover@intel.com> | 2017-04-03 22:05:30 +0000 |
commit | 8f460655a26fb564a15cb927382fed4b69f41c67 (patch) | |
tree | ea2ddf6dc6bede61d1c3b7e75d53749dbaae87bc /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 74a7fa059484465536cb4f5040da056ae4d9699b (diff) | |
download | bcm5719-llvm-8f460655a26fb564a15cb927382fed4b69f41c67.tar.gz bcm5719-llvm-8f460655a26fb564a15cb927382fed4b69f41c67.zip |
InstSimplify: Add a hook for shufflevector
Summary:
Add a hook for simplification of shufflevector's with the following rules:
- Constant folding - NFC, as it was already being done by the default handler.
- If only one of the operands is constant, constant fold the shuffle if the
mask does not select elements from the variable operand - to show the hook is firing and affecting the test-cases.
Reviewers: RKSimon, craig.topper, spatel, sanjoy, nlopes, majnemer
Reviewed By: spatel
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D31525
llvm-svn: 299393
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 6294d195cea..5cb93df7395 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4081,6 +4081,50 @@ Value *llvm::SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, RecursionLimit); } +static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, + Type *RetTy, const Query &Q, + unsigned MaxRecurse) { + unsigned MaskNumElts = Mask->getType()->getVectorNumElements(); + unsigned InVecNumElts = Op0->getType()->getVectorNumElements(); + + auto *Op0Const = dyn_cast<Constant>(Op0); + auto *Op1Const = dyn_cast<Constant>(Op1); + + // If all operands are constant, constant fold the shuffle. + if (Op0Const && Op1Const) + return ConstantFoldShuffleVectorInstruction(Op0Const, Op1Const, Mask); + + // If only one of the operands is constant, constant fold the shuffle if the + // mask does not select elements from the variable operand. + bool MaskSelects0 = false, MaskSelects1 = false; + for (unsigned i = 0; i != MaskNumElts; ++i) { + int Idx = ShuffleVectorInst::getMaskValue(Mask, i); + if (Idx == -1) + continue; + if ((unsigned)Idx < InVecNumElts) + MaskSelects0 = true; + else + MaskSelects1 = true; + } + if (!MaskSelects0 && Op1Const) + return ConstantFoldShuffleVectorInstruction(UndefValue::get(Op0->getType()), + Op1Const, Mask); + if (!MaskSelects1 && Op0Const) + return ConstantFoldShuffleVectorInstruction( + Op0Const, UndefValue::get(Op0->getType()), Mask); + + return nullptr; +} + +/// Given operands for a ShuffleVectorInst, fold the result or return null. +Value *llvm::SimplifyShuffleVectorInst( + Value *Op0, Value *Op1, Constant *Mask, Type *RetTy, + const DataLayout &DL, const TargetLibraryInfo *TLI, const DominatorTree *DT, + AssumptionCache *AC, const Instruction *CxtI) { + return ::SimplifyShuffleVectorInst( + Op0, Op1, Mask, RetTy, Query(DL, TLI, DT, AC, CxtI), RecursionLimit); +} + //=== Helper functions for higher up the class hierarchy. /// Given operands for a BinaryOperator, see if we can fold the result. @@ -4569,6 +4613,13 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL, EEI->getVectorOperand(), EEI->getIndexOperand(), DL, TLI, DT, AC, I); break; } + case Instruction::ShuffleVector: { + auto *SVI = cast<ShuffleVectorInst>(I); + Result = SimplifyShuffleVectorInst(SVI->getOperand(0), SVI->getOperand(1), + SVI->getMask(), SVI->getType(), DL, TLI, + DT, AC, I); + break; + } case Instruction::PHI: Result = SimplifyPHINode(cast<PHINode>(I), Query(DL, TLI, DT, AC, I)); break; |