[llvm] [RISCV] Decompose LMUL > 1 reverses into LMUL * M1 vrgather.vv (PR #104574)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 14:47:37 PDT 2024


================
@@ -10320,6 +10320,54 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
     Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
   }
 
+  MVT XLenVT = Subtarget.getXLenVT();
+  auto [Mask, VL] = getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget);
+
+  // On most uarchs vrgather.vv is quadratic in LMUL because each output
+  // register may read from LMUL registers. However to reverse a vector each
+  // output register only needs to read from one register. So decompose it into
+  // LMUL * M1 vrgather.vvs, so we get O(LMUL) performance instead of O(LMUL^2).
+  //
+  // vsetvli a1, zero, e64, m4, ta, ma
+  // vrgatherei16.vv v12, v8, v16
+  // ->
+  // vsetvli a1, zero, e64, m1, ta, ma
+  // vrgather.vv v15, v8, v16
+  // vrgather.vv v14, v9, v16
+  // vrgather.vv v13, v10, v16
+  // vrgather.vv v12, v11, v16
+  if (ContainerVT.bitsGT(getLMUL1VT(ContainerVT)) &&
+      ContainerVT.getVectorElementCount().isKnownMultipleOf(2)) {
+    MVT HalfVT = ContainerVT.getHalfNumVectorElementsVT();
+    SDValue Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, Vec,
----------------
topperc wrote:

DAG.getSplitVector?

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


More information about the llvm-commits mailing list