[llvm] [RISCV] Use vleff's AVL when output VL doesn't dominate in RISCVVLOptimizer (PR #156618)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 3 10:13:40 PDT 2025


https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/156618

>From 9bdf90af849b91c39eb101a7d1b50074f87386c6 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Wed, 3 Sep 2025 16:08:35 +0800
Subject: [PATCH 1/3] Precommit tests

---
 llvm/test/CodeGen/RISCV/rvv/vl-opt.mir | 46 ++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
index 60398cdf1db66..383250de2a350 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
@@ -603,4 +603,50 @@ body: |
     $x10 = COPY %9
     PseudoRET implicit $x10
 ...
+---
+name: vleff_imm
+body: |
+  bb.0:
+    ; CHECK-LABEL: name: vleff_imm
+    ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+    %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+    PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
+---
+name: vleff_reg_dominates
+body: |
+  bb.0:
+    liveins: $x8
+    ; CHECK-LABEL: name: vleff_reg_dominates
+    ; CHECK: liveins: $x8
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+    ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+    %avl:gprnox0 = COPY $x8
+    %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+    PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
+---
+name: vleff_reg_doesnt_dominate
+body: |
+  bb.0:
+    liveins: $x8
+    ; CHECK-LABEL: name: vleff_reg_doesnt_dominate
+    ; CHECK: liveins: $x8
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+    ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+    %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    %avl:gprnox0 = COPY $x8
+    %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+    PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
 

>From 4b860bb4f5f123778bdbca89de176cacb2c30f8a Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Wed, 3 Sep 2025 16:28:15 +0800
Subject: [PATCH 2/3] [RISCV] Use vleff's AVL when output VL doesn't dominate
 in RISCVVLOptimizer

If an instruction's demanded VL is a virtual register defined by a vleff instruction, it might not dominate and fail to have its VL reduced.

In leiu of the output VL, we can try and use the AVL passed to the vleff itself since it will be at least greater than or equal the original VL.

I tried to create an LLVM IR test for this in but didn't have any luck because the scheduler kept on moving the instruction past the vleff, so it always dominated. So I've just included some mir tests instead.
---
 llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp | 9 +++++++++
 llvm/test/CodeGen/RISCV/rvv/vl-opt.mir     | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
index 9b70eb6c25b12..9764f3eb3d78b 100644
--- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
@@ -1464,6 +1464,15 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) const {
   assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
          "Expected VL to be an Imm or virtual Reg");
 
+  // If the VL is defined by a vleff that doesn't dominate MI, try using the
+  // vleff's AVL. It will be greater than or equal to the output VL.
+  if (CommonVL->isReg()) {
+    const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
+    if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
+        !MDT->dominates(VLMI, &MI))
+      CommonVL = VLMI->getOperand(4);
+  }
+
   if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
     LLVM_DEBUG(dbgs() << "  Abort due to CommonVL not <= VLOp.\n");
     return false;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
index 383250de2a350..a474722d2f380 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
@@ -608,7 +608,7 @@ name: vleff_imm
 body: |
   bb.0:
     ; CHECK-LABEL: name: vleff_imm
-    ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
     ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
     ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
     %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
@@ -624,7 +624,7 @@ body: |
     ; CHECK: liveins: $x8
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
-    ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
     ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
     ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
     %avl:gprnox0 = COPY $x8

>From 712d2fc886e0cd786fca5857f756ee53c664d7a2 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 4 Sep 2025 01:13:17 +0800
Subject: [PATCH 3/3] Use correct VL operand with masked vleff

---
 llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp |  2 +-
 llvm/test/CodeGen/RISCV/rvv/vl-opt.mir     | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
index 9764f3eb3d78b..baf6aaac62779 100644
--- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
@@ -1470,7 +1470,7 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) const {
     const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
     if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
         !MDT->dominates(VLMI, &MI))
-      CommonVL = VLMI->getOperand(4);
+      CommonVL = VLMI->getOperand(RISCVII::getVLOpNum(VLMI->getDesc()));
   }
 
   if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
index a474722d2f380..0acdca91ee84c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
@@ -649,4 +649,15 @@ body: |
     %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
     PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
 ...
-
+---
+name: vleff_mask_imm
+body: |
+  bb.0:
+    ; CHECK-LABEL: name: vleff_mask_imm
+    ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: %y:vrnov0, %vl:gprnox0 = PseudoVLE8FF_V_M1_MASK $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+    ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+    %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+    %y:vrnov0, %vl:gprnox0 = PseudoVLE8FF_V_M1_MASK $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+    PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...



More information about the llvm-commits mailing list