[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