================
@@ -1252,6 +1252,43 @@ Value *llvm::concatenateVectors(IRBuilderBase &Builder,
return ResList[0];
}
+Value *llvm::repeatVector(IRBuilderBase &Builder, Value *Vec,
+ ElementCount Factor) {
+ assert(isa<FixedVectorType>(Vec->getType()));
+ assert(Factor.isScalable() || Factor.getKnownMinValue() > 1);
+
+ // If the vector was already a constant splat, just recreate it with a
+ // bigger element count.
+ auto *InVTy = cast<FixedVectorType>(Vec->getType());
+ if (auto *VectorConstant = dyn_cast<Constant>(Vec);
+ VectorConstant && VectorConstant->getSplatValue()) {
+ ElementCount NewEC = Factor.multiplyCoefficientBy(InVTy->getNumElements());
+ return Builder.CreateVectorSplat(NewEC, VectorConstant->getSplatValue());
+ }
+
+ if (Factor.getKnownMinValue() > 1) {
+ unsigned NumFixedElts = InVTy->getNumElements() *
Factor.getKnownMinValue();
+ SmallVector<int, 16> Mask(NumFixedElts);
+ for (unsigned Idx = 0; Idx != NumFixedElts; ++Idx)
+ Mask[Idx] = Idx % InVTy->getNumElements();
+ Vec = Builder.CreateShuffleVector(Vec, Mask);
+ }
+
+ if (Factor.isScalable()) {
+ auto *WideTy = toVectorTy(InVTy, Factor);
+ return Builder.CreateIntrinsic(Intrinsic::vector_repeat,
+ {WideTy, Vec->getType()}, {Vec});
+ }
+ return Vec;
+}
+
+Value *llvm::broadcastOrRepeatValue(IRBuilderBase &Builder, Value *V,
+ ElementCount Factor) {
+ if (V->getType()->isVectorTy())
+ return repeatVector(Builder, V, Factor);
+ return Builder.CreateVectorSplat(Factor, V, "broadcast");
+}
----------------
gbossu wrote:
I think that's a good discussion point to bring up.
I believe your point is not really reduce the diff but just keep the change
under `Transforms/Vectorize/`? Given this is a generic IRBuilder helper for the
new `vector.repeat` intrinsic, I feel `VectorUtils.cpp` is a suitable place for
it.
I'd need to see how introducing an explicit `VPI::Broadcast` would work. I'm
guessing this would require a new VPTransform pass to ensure that any call to
`VPTransformState::get` does not require the introduction of a `vector.repeat`
intrinsic. Effectively, "broadcasting" vector values to wider vectors would
happen via an explicit VPInstruction, while it could still remain in
`VPTransformState::get` for scalar values. The asymmetry bothers me a bit.
@fhahn I'd be happy to hear your thoughts on how you envision broadcasting
values in `VPTransformState::get` and whether the handling should differ for
input scalar vs vector values. I.e. long-term, do you expect no broadcasting to
happen in that function because it would have been modelled with explicit
VPInstructions prior?
https://github.com/llvm/llvm-project/pull/208213
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits