[llvm] [RISCV] Teach the VL Optimizer about Zvzip instructions (PR #214405)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 5 23:54:15 PDT 2026


================
@@ -2423,3 +2424,111 @@ body: |
     %2:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 3 /* ta, ma */
     PseudoVSOXSEG3EI32_V_M1_M2 $noreg, $noreg, %2, 1, 6 /* e64 */
 ...
+---
+name:            vzip_vv_vd
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vzip_vv_vd
+    ; CHECK: early-clobber %0:vrm2 = PseudoVZIP_VV_M1 $noreg, $noreg, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: [[PseudoVADD_VV_M2_:%[0-9]+]]:vrm2 = PseudoVADD_VV_M2 $noreg, %0, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: $v8m2 = COPY [[PseudoVADD_VV_M2_]]
+    early-clobber %0:vrm2 = PseudoVZIP_VV_M1 $noreg, $noreg, $noreg, -1, 5, 0
+    %1:vrm2 = PseudoVADD_VV_M2 $noreg, %0, $noreg, 1, 5, 0
+    $v8m2 = COPY %1
+...
+---
+name:            vzip_vv_incompatible_eew
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vzip_vv_incompatible_eew
+    ; CHECK: early-clobber %0:vrm2 = PseudoVZIP_VV_M1 $noreg, $noreg, $noreg, -1 /* vl=VLMAX */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: [[PseudoVADD_VV_M2_:%[0-9]+]]:vrm2 = PseudoVADD_VV_M2 $noreg, %0, $noreg, 1 /* vl */, 4 /* e16 */, 0 /* tu, mu */
+    ; CHECK-NEXT: $v8m2 = COPY [[PseudoVADD_VV_M2_]]
+    early-clobber %0:vrm2 = PseudoVZIP_VV_M1 $noreg, $noreg, $noreg, -1, 5, 0
+    %1:vrm2 = PseudoVADD_VV_M2 $noreg, %0, $noreg, 1, 4, 0
+    $v8m2 = COPY %1
+...
+---
+name:            vunzipe_v
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vunzipe_v
+    ; CHECK: early-clobber %0:vr = PseudoVUNZIPE_V_M1 $noreg, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]]
+    early-clobber %0:vr = PseudoVUNZIPE_V_M1 $noreg, $noreg, -1, 5, 0
+    %1:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1, 5, 0
+    $v8 = COPY %1
+...
+---
+name:            vunzipo_v
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vunzipo_v
+    ; CHECK: early-clobber %0:vr = PseudoVUNZIPO_V_M1 $noreg, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]]
+    early-clobber %0:vr = PseudoVUNZIPO_V_M1 $noreg, $noreg, -1, 5, 0
+    %1:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1, 5, 0
+    $v8 = COPY %1
+...
+---
+name:            vunzipe_incompatible_eew
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vunzipe_incompatible_eew
+    ; CHECK: early-clobber %0:vr = PseudoVUNZIPE_V_M1 $noreg, $noreg, -1 /* vl=VLMAX */, 5 /* e32 */, 0 /* tu, mu */
+    ; CHECK-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1 /* vl */, 4 /* e16 */, 0 /* tu, mu */
+    ; CHECK-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]]
+    early-clobber %0:vr = PseudoVUNZIPE_V_M1 $noreg, $noreg, -1, 5, 0
+    %1:vr = PseudoVADD_VV_M1 $noreg, %0, $noreg, 1, 4, 0
+    $v8 = COPY %1
+...
+---
+name:            vunzipe_src_propagate
+body:             |
+  bb.0:
+    ; CHECK-LABEL: name: vunzipe_src_propagate
+    ; CHECK: %src:vrm2 = PseudoVADD_VV_M2 $noreg, $noreg, $noreg, 1 /* vl */, 5 /* e32 */, 0 /* tu, mu */
----------------
lukel97 wrote:

I don't think this is correct with v0.1 of the spec as unzip reads 2 * vl. `getMinimumVLForUser` will need to be updated to handle the effective vl.

For the proposed v0.2 of the spec we would need to implement the ceil/floor rules which seems kind of complicated. I'm still hoping your suggestion that `vl` controls the destination register is accepted (https://github.com/riscv/riscv-isa-manual/pull/3233#issuecomment-4902737960). That would make things much easier. 

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


More information about the llvm-commits mailing list