[llvm] [IA][RISCV] Support VP loads/stores in InterleavedAccessPass (PR #120490)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 01:03:22 PST 2025


================
@@ -630,11 +630,34 @@ getVectorDeinterleaveFactor(IntrinsicInst *II,
   return true;
 }
 
+/// Check the interleaved mask
+///
+/// - if a value within the optional is non-nullptr, the value corresponds to
+///   deinterleaved mask
+/// - if a value within the option is nullptr, the value corresponds to all-true
+///   mask
+/// - return nullopt if mask cannot be deinterleaved
+static Value *getMask(Value *WideMask, unsigned Factor) {
+  using namespace llvm::PatternMatch;
+  if (auto *IMI = dyn_cast<IntrinsicInst>(WideMask)) {
+    SmallVector<Value *, 8> Operands;
+    SmallVector<Instruction *, 8> DeadInsts;
+    if (getVectorInterleaveFactor(IMI, Operands, DeadInsts)) {
+      assert(!Operands.empty());
+      if (Operands.size() == Factor && llvm::all_equal(Operands))
+        return Operands[0];
+    }
+  }
+  if (match(WideMask, m_AllOnes()))
+    return WideMask;
----------------
lukel97 wrote:

This returns a different sized mask from the interleaved case, but it looks like the interleave intrinsics don't currently check the mask type which is why this works?

E.g. I tried out

```llvm
  %0 = tail call target("riscv.vector.tuple", <vscale x 1 x i8>, 2) @llvm.riscv.vlseg2.mask.triscv.vector.tuple_nxv1i8_2t.nxv2i1(target("riscv.vector.tuple", <vscale x 1 x i8>, 2) undef, ptr %base, <vscale x 4 x i1> %mask, i64 %vl, i64 1, i64 3)
```

And it seems to compile. I think we're missing a constraint on the intrinsics.

I think we need to return a new constant splat vector with the segment type here

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


More information about the llvm-commits mailing list