================
@@ -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

Reply via email to