diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2020-10-11 10:31:17 +0100 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2020-10-11 10:31:17 +0100 |
commit | b752daa26b641550e1d5b99d4b89230011c2c0cc (patch) | |
tree | 33116ebb24b93ccab28e219ed466148f59ed33f4 /llvm/lib/IR/Constants.cpp | |
parent | 93377888ae89560ba6d3976e2762d3d4724c4dfd (diff) | |
download | llvm-b752daa26b641550e1d5b99d4b89230011c2c0cc.zip llvm-b752daa26b641550e1d5b99d4b89230011c2c0cc.tar.gz llvm-b752daa26b641550e1d5b99d4b89230011c2c0cc.tar.bz2 |
[InstCombine] Replace getLogBase2 internal helper with ConstantExpr::getExactLogBase2. NFCI.
This exposes the helper for other power-of-2 instcombine folds that I'm intending to add vector support to.
The helper only operated on power-of-2 constants so getExactLogBase2 is a more accurate name.
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index d0c1e37..9f83861 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -2547,6 +2547,35 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) { isExact ? PossiblyExactOperator::IsExact : 0); } +Constant *ConstantExpr::getExactLogBase2(Constant *C) { + Type *Ty = C->getType(); + const APInt *IVal; + if (match(C, m_APInt(IVal)) && IVal->isPowerOf2()) + return ConstantInt::get(Ty, IVal->logBase2()); + + // FIXME: We can extract pow of 2 of splat constant for scalable vectors. + auto *VecTy = dyn_cast<FixedVectorType>(Ty); + if (!VecTy) + return nullptr; + + SmallVector<Constant *, 4> Elts; + for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) { + Constant *Elt = C->getAggregateElement(I); + if (!Elt) + return nullptr; + // Note that log2(iN undef) is *NOT* iN undef, because log2(iN undef) u< N. + if (isa<UndefValue>(Elt)) { + Elts.push_back(Constant::getNullValue(Ty->getScalarType())); + continue; + } + if (!match(Elt, m_APInt(IVal)) || !IVal->isPowerOf2()) + return nullptr; + Elts.push_back(ConstantInt::get(Ty->getScalarType(), IVal->logBase2())); + } + + return ConstantVector::get(Elts); +} + Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant) { assert(Instruction::isBinaryOp(Opcode) && "Only binops allowed"); |