SValue X, Y;
// If present, add 1 << RoundAt before shift:
std::optional<unsigned> RoundAt;
+ VectorType *ResTy;
};
auto getNumSignificantBits(Value *V, Instruction *In) const
// Match
// (X * Y) [>> N], or
-// ((X * Y) + (1 << N-1)) >> N
+// ((X * Y) + (1 << M)) >> N
auto HvxIdioms::matchFxpMul(Instruction &In) const -> std::optional<FxpOp> {
using namespace PatternMatch;
auto *Ty = In.getType();
// FIXME: The information below is recomputed.
Op.X.Sgn = getNumSignificantBits(Op.X.Val, &In).second;
Op.Y.Sgn = getNumSignificantBits(Op.Y.Val, &In).second;
+ Op.ResTy = cast<VectorType>(Ty);
return Op;
}
SmallVector<Value *> Results;
FxpOp ChopOp = Op;
+ ChopOp.ResTy = VectorType::get(Op.ResTy->getElementType(), ChopLen, false);
for (unsigned V = 0; V != VecLen / ChopLen; ++V) {
ChopOp.X.Val = HVC.subvector(Builder, X, V * ChopLen, ChopLen);
if (SkipWords != 0)
WordP.resize(WordP.size() - SkipWords);
- return HVC.joinVectorElements(Builder, WordP, InpTy);
+ return HVC.joinVectorElements(Builder, WordP, Op.ResTy);
}
auto HvxIdioms::createMulQ15(IRBuilderBase &Builder, SValue X, SValue Y,
unsigned NeedInputs = ToWidth / Width;
if (Inputs.size() != NeedInputs) {
+ // Having too many inputs is ok: drop the high bits (usual wrap-around).
+ // If there are too few, fill them with the sign bit.
Value *Last = Inputs.back();
Value *Sign =
Builder.CreateAShr(Last, getConstSplat(Last->getType(), Width - 1));