[llvm] cfe9def - [RISCV][Verifier] Check operands and result type of RISC-V vsetvli/vsetvlimax (#218594)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 25 20:43:11 PDT 2026
Author: Pengcheng Wang
Date: 2026-08-26T03:43:06Z
New Revision: cfe9def9a4149c7aa1db2dcb7adcef439d763d63
URL: https://github.com/llvm/llvm-project/commit/cfe9def9a4149c7aa1db2dcb7adcef439d763d63
DIFF: https://github.com/llvm/llvm-project/commit/cfe9def9a4149c7aa1db2dcb7adcef439d763d63.diff
LOG: [RISCV][Verifier] Check operands and result type of RISC-V vsetvli/vsetvlimax (#218594)
The result of `llvm.riscv.vsetvli/vsetvlimax` models VLMAX (or a VL bounded
by it) and is only defined for XLen, so the result type must be i32 or i64.
Narrower types cannot represent the architectural VLMAX range of [1, 65536]
that value analyses rely on.
Also check that the VSEW and VLMUL immediate operands encode a valid
SEW/LMUL pair (VSEW <= 3, VLMUL != reserved), so that consumers can
assume a well-formed vtype.
Assisted-by: TRAE CLI (Opus 4.8)
Added:
llvm/test/Verifier/RISCV/vsetvli.ll
Modified:
llvm/lib/IR/Verifier.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 9cef4b05f19e5..7b78acc5aba56 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -99,6 +99,7 @@
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
+#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
@@ -126,6 +127,7 @@
#include "llvm/Support/ModRef.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Coroutines/CoroInstr.h"
#include <algorithm>
@@ -6976,6 +6978,26 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
Call);
break;
}
+ case Intrinsic::riscv_vsetvli:
+ case Intrinsic::riscv_vsetvlimax: {
+ // The result models VLMAX (or a VL bounded by it) and is only defined for
+ // XLen (i32/i64). Narrower types cannot represent the architectural VLMAX
+ // range of [1, 65536], which value analyses rely on.
+ Check(Call.getType()->isIntegerTy(32) || Call.getType()->isIntegerTy(64),
+ "llvm.riscv.vsetvli/vsetvlimax result must be i32 or i64", &Call);
+
+ // VSEW and VLMUL select the vtype and must encode a valid SEW/LMUL pair.
+ bool HasAVL = ID == Intrinsic::riscv_vsetvli;
+ unsigned Offset = HasAVL ? 1 : 0;
+ uint64_t VSEW =
+ cast<ConstantInt>(Call.getArgOperand(Offset))->getZExtValue();
+ uint64_t VLMUL =
+ cast<ConstantInt>(Call.getArgOperand(Offset + 1))->getZExtValue();
+ Check(VSEW <= 3, "llvm.riscv.vsetvli/vsetvlimax VSEW must be 0-3", &Call);
+ Check(VLMUL <= 7 && VLMUL != RISCVVType::LMUL_RESERVED,
+ "llvm.riscv.vsetvli/vsetvlimax VLMUL is reserved", &Call);
+ break;
+ }
case Intrinsic::callbr_landingpad: {
const auto *CBR = dyn_cast<CallBrInst>(Call.getOperand(0));
Check(CBR, "intrinstic requires callbr operand", &Call);
diff --git a/llvm/test/Verifier/RISCV/vsetvli.ll b/llvm/test/Verifier/RISCV/vsetvli.ll
new file mode 100644
index 0000000000000..82c13a4416c67
--- /dev/null
+++ b/llvm/test/Verifier/RISCV/vsetvli.ll
@@ -0,0 +1,25 @@
+; RUN: not opt -passes=verify -S < %s 2>&1 | FileCheck %s
+
+; CHECK: llvm.riscv.vsetvli/vsetvlimax result must be i32 or i64
+define i16 @narrow_result() {
+ %vl = call i16 @llvm.riscv.vsetvlimax.i16(i16 0, i16 3)
+ ret i16 %vl
+}
+
+; CHECK: llvm.riscv.vsetvli/vsetvlimax VSEW must be 0-3
+define i64 @bad_vsew() {
+ %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 5, i64 0)
+ ret i64 %vl
+}
+
+; CHECK: llvm.riscv.vsetvli/vsetvlimax VLMUL is reserved
+define i64 @reserved_vlmul() {
+ %vl = call i64 @llvm.riscv.vsetvlimax.i64(i64 0, i64 4)
+ ret i64 %vl
+}
+
+; CHECK: llvm.riscv.vsetvli/vsetvlimax VSEW must be 0-3
+define i64 @vsetvli_bad_vsew(i64 %avl) {
+ %vl = call i64 @llvm.riscv.vsetvli.i64(i64 %avl, i64 7, i64 0)
+ ret i64 %vl
+}
More information about the llvm-commits
mailing list