[llvm] [RISCV][TTI] Recognize CONCAT_VECTORS if a shufflevector mask is multiple insert subvector. (PR #111459)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 20:23:57 PDT 2024


================
@@ -343,6 +343,49 @@ RISCVTTIImpl::getConstantPoolLoadCost(Type *Ty,  TTI::TargetCostKind CostKind) {
                              /*AddressSpace=*/0, CostKind);
 }
 
+InstructionCost
+RISCVTTIImpl::isMultipleInsertSubvector(VectorType *Tp, ArrayRef<int> Mask,
+                                        TTI::TargetCostKind CostKind) {
+  if (!isa<FixedVectorType>(Tp))
+    return InstructionCost::getInvalid();
+  std::pair<InstructionCost, MVT> LT = getTypeLegalizationCost(Tp);
+  if (LT.second.getScalarSizeInBits() == 1)
+    return InstructionCost::getInvalid();
+  unsigned Size = Mask.size();
+  if (!isPowerOf2_32(Size))
+    return InstructionCost::getInvalid();
+  // Try to guess SubTp.
+  for (unsigned SubVecSize = 1; SubVecSize < Size; SubVecSize <<= 1) {
+    SmallVector<int> RepeatedPattern(createSequentialMask(0, SubVecSize, 0));
+    bool Skip = false;
+    for (unsigned I = 0; I != Size; I += SubVecSize)
----------------
lukel97 wrote:

>From https://github.com/llvm/llvm-project/pull/110457#discussion_r1790533499

I think you can avoid the nested loop if you first calculate the SubVecSize on its own rather than guessing it:
```c
for (int i = 0; i < Size; i++) {
  if (Mask[i] == i) continue;
  else if (Mask[i] == 0) { SubVecSize = i; break; }
  else return InstructionCost::getInvalid();
}
```

And then you can check the rest of the mask separately:

```c
for (int i = 0; i < Size; i++)
  if (Mask[i] != i % SubVecSize)
    return InstructionCost::getInvalid();
```

https://github.com/llvm/llvm-project/pull/111459


More information about the llvm-commits mailing list