[llvm] [RISCV] Infer vl > 0 if AVL > 0 in range attributes (PR #219385)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 23:37:35 PDT 2026


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

>From 5cd1f1de5b2f0937475f3b26f30f4553c241b6a3 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 28 Aug 2026 14:33:43 +0800
Subject: [PATCH 1/3] Precommit test

---
 .../InstCombine/RISCV/riscv-vsetvli-range.ll        | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
index ef1fe05c79d60..7e66ad57859ff 100644
--- a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
+++ b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
@@ -123,3 +123,16 @@ define i1 @vsetvli_runtime_avl_gt_max_folds(i64 %avl) {
   %c = icmp ugt i64 %vl, 8192
   ret i1 %c
 }
+
+; vl known > 0, so range must be 0
+define i64 @vsetvli_vl_known_nonzero(i64 %x) {
+; CHECK-LABEL: define i64 @vsetvli_vl_known_nonzero(
+; CHECK-SAME: i64 [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[AVL:%.*]] = add nuw i64 [[X]], 1
+; CHECK-NEXT:    [[VL:%.*]] = call range(i64 0, 8193) i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
+; CHECK-NEXT:    ret i64 [[VL]]
+;
+  %avl = add nuw i64 %x, 1
+  %vl = call i64 @llvm.riscv.vsetvli.i64(i64 %avl, i64 0, i64 0)
+  ret i64 %vl
+}

>From 6b8170c90abccff4581d3fac172bb8e359f123a4 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 28 Aug 2026 14:35:04 +0800
Subject: [PATCH 2/3] [RISCV] Infer vl > 0 if AVL > 0 in range attributes

A follow up from #218652, a non-zero AVL guarantees a non-zero vl per
the spec
---
 llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp | 14 ++++++++------
 .../InstCombine/RISCV/riscv-vsetvli-range.ll       |  6 +++---
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
index b6e4ea982f889..f51e47895c4bb 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
@@ -3787,17 +3787,19 @@ RISCVTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
     ConstantRange VLRange = VLMAXRange;
     if (HasAVL) {
       APInt MaxVL = VLMAXRange.getUnsignedMax();
-      if (auto *AVL = dyn_cast<ConstantInt>(II.getArgOperand(0))) {
-        const APInt &C = AVL->getValue();
+      Value *AVL = II.getArgOperand(0);
+      // vl > 0 if AVL > 0
+      APInt MinVL = APInt(BitWidth, isKnownNonZero(AVL, DL) ? 1 : 0);
+      if (auto *AVLC = dyn_cast<ConstantInt>(AVL)) {
+        const APInt &C = AVLC->getValue();
         // A constant AVL not exceeding the smallest possible VLMAX means vl is
         // exactly AVL, so replace the intrinsic with that constant.
         if (C.ule(VLMAXRange.getUnsignedMin()))
           return IC.replaceInstUsesWith(II, ConstantInt::get(II.getType(), C));
-        VLRange = ConstantRange::getNonEmpty(APInt::getZero(BitWidth),
-                                             APIntOps::umin(C, MaxVL) + 1);
-      } else {
         VLRange =
-            ConstantRange::getNonEmpty(APInt::getZero(BitWidth), MaxVL + 1);
+            ConstantRange::getNonEmpty(MinVL, APIntOps::umin(C, MaxVL) + 1);
+      } else {
+        VLRange = ConstantRange::getNonEmpty(MinVL, MaxVL + 1);
       }
     }
 
diff --git a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
index 7e66ad57859ff..4e0592f5f23bd 100644
--- a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
+++ b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
@@ -38,7 +38,7 @@ define i64 @vsetvli_const_avl_at_min128() {
 define i64 @vsetvli_const_avl_mid() {
 ; VLEN128-LABEL: define i64 @vsetvli_const_avl_mid(
 ; VLEN128-SAME: ) #[[ATTR0]] {
-; VLEN128-NEXT:    [[VL:%.*]] = call range(i64 0, 21) i64 @llvm.riscv.vsetvli.i64(i64 20, i64 0, i64 0)
+; VLEN128-NEXT:    [[VL:%.*]] = call range(i64 1, 21) i64 @llvm.riscv.vsetvli.i64(i64 20, i64 0, i64 0)
 ; VLEN128-NEXT:    ret i64 [[VL]]
 ;
 ; VLEN512-LABEL: define i64 @vsetvli_const_avl_mid(
@@ -54,7 +54,7 @@ define i64 @vsetvli_const_avl_mid() {
 define i64 @vsetvli_const_avl_above_max() {
 ; CHECK-LABEL: define i64 @vsetvli_const_avl_above_max(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[VL:%.*]] = call range(i64 0, 8193) i64 @llvm.riscv.vsetvli.i64(i64 100000, i64 0, i64 0)
+; CHECK-NEXT:    [[VL:%.*]] = call range(i64 1, 8193) i64 @llvm.riscv.vsetvli.i64(i64 100000, i64 0, i64 0)
 ; CHECK-NEXT:    ret i64 [[VL]]
 ;
   %vl = call i64 @llvm.riscv.vsetvli.i64(i64 100000, i64 0, i64 0)
@@ -129,7 +129,7 @@ define i64 @vsetvli_vl_known_nonzero(i64 %x) {
 ; CHECK-LABEL: define i64 @vsetvli_vl_known_nonzero(
 ; CHECK-SAME: i64 [[X:%.*]]) #[[ATTR0]] {
 ; CHECK-NEXT:    [[AVL:%.*]] = add nuw i64 [[X]], 1
-; CHECK-NEXT:    [[VL:%.*]] = call range(i64 0, 8193) i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
+; CHECK-NEXT:    [[VL:%.*]] = call range(i64 1, 8193) i64 @llvm.riscv.vsetvli.i64(i64 [[AVL]], i64 0, i64 0)
 ; CHECK-NEXT:    ret i64 [[VL]]
 ;
   %avl = add nuw i64 %x, 1

>From 53817d78719dc8b7b086f88a890bc1cae950d302 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 28 Aug 2026 14:37:06 +0800
Subject: [PATCH 3/3] Fix typo

---
 llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
index 4e0592f5f23bd..837ae6a9eb702 100644
--- a/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
+++ b/llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-range.ll
@@ -124,7 +124,7 @@ define i1 @vsetvli_runtime_avl_gt_max_folds(i64 %avl) {
   ret i1 %c
 }
 
-; vl known > 0, so range must be 0
+; vl known > 0, so range must be > 0
 define i64 @vsetvli_vl_known_nonzero(i64 %x) {
 ; CHECK-LABEL: define i64 @vsetvli_vl_known_nonzero(
 ; CHECK-SAME: i64 [[X:%.*]]) #[[ATTR0]] {



More information about the llvm-commits mailing list