[llvm] [RISCV] Prevent emitting vsetvli with e32alt or e64alt. (PR #191960)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 23:08:46 PDT 2026
https://github.com/topperc created https://github.com/llvm/llvm-project/pull/191960
The e32alt and e64alt encodings for vtype are reserved.
Non-fp instructions ignore altfmt and we want to use that to avoid
vtype toggle when using load, store, slide, gather, etc. to manipulate
bf16 vectors. This is why we have a Demanded bit for AltFmt.
We need to make sure we don't keep the AltFmt set when we're changing
SEW to 32 or 64.
>From 6803b453c96b193fc5b6242db19f1ae565d2dbd1 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 13 Apr 2026 22:51:35 -0700
Subject: [PATCH 1/2] Pre-commit test
---
.../RISCV/rvv/mixed-float-bf16-arith.ll | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll b/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
index 0f3ebb9e625ad..ef998be8f1d42 100644
--- a/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
@@ -166,3 +166,26 @@ entry:
ret <vscale x 1 x bfloat> %a
}
+
+define <8 x i64> @test_bf16_i64(<8 x i64> %v, <8 x bfloat> %v2, ptr %p) {
+; CHECK-LABEL: test_bf16_i64:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma
+; CHECK-NEXT: vid.v v16
+; CHECK-NEXT: vsetvli zero, zero, e16alt, m1, ta, ma
+; CHECK-NEXT: vfmv.f.s fa5, v12
+; CHECK-NEXT: fmv.w.x fa4, zero
+; CHECK-NEXT: vsetvli zero, zero, e64alt, m4, ta, ma
+; CHECK-NEXT: vadd.vv v12, v16, v16
+; CHECK-NEXT: fcvt.s.bf16 fa5, fa5
+; CHECK-NEXT: vadd.vv v8, v8, v12
+; CHECK-NEXT: fadd.s fa5, fa5, fa4
+; CHECK-NEXT: fcvt.bf16.s fa5, fa5
+; CHECK-NEXT: fsh fa5, 0(a0)
+; CHECK-NEXT: ret
+ %vp2 = add <8 x i64> %v, <i64 poison, i64 2, i64 4, i64 6, i64 8, i64 10, i64 12, i64 14>
+ %sum2 = fadd <8 x bfloat> zeroinitializer, %v2
+ %s0 = extractelement <8 x bfloat> %sum2, i64 0
+ store bfloat %s0, ptr %p
+ ret <8 x i64> %vp2
+}
>From c2beff81226d008235e5906fefea30358d0acc3d Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 13 Apr 2026 22:55:16 -0700
Subject: [PATCH 2/2] [RISCV] Prevent emitting vsetvli with e32alt or e64alt.
The e32alt and e64alt encodings for vtype are reserved.
Non-fp instructions ignore altfmt and we want to use that to avoid
vtype toggle when using load, store, slide, gather, etc. to manipulate
bf16 vectors. This is why we have a Demanded bit for AltFmt.
We need to make sure we don't keep the AltFmt set when we're changing
SEW to 32 or 64.
---
.../llvm/TargetParser/RISCVTargetParser.h | 16 +++++++++++-----
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 3 +--
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 9 ++++++---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 ++--
.../CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll | 2 +-
5 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index b0ed9efcb9d82..110b71a6341a6 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -174,17 +174,23 @@ inline static unsigned getXSfmmWiden(unsigned VType) {
return 1 << (TWiden - 1);
}
-static inline bool isValidXSfmmVType(unsigned VTypeI) {
- return (VTypeI & ~0x738) == 0 && RISCVVType::hasXSfmmWiden(VTypeI) &&
- RISCVVType::getSEW(VTypeI) * RISCVVType::getXSfmmWiden(VTypeI) <= 64;
-}
-
inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
inline static bool isAltFmt(unsigned VType) { return VType & 0x100; }
+inline static bool isValidVType(unsigned VType) {
+ return getSEW(VType) <= 64 && getVLMUL(VType) != LMUL_RESERVED &&
+ (!isAltFmt(VType) || getSEW(VType) < 32);
+}
+
+static inline bool isValidXSfmmVType(unsigned VTypeI) {
+ return (VTypeI & ~0x738) == 0 && RISCVVType::hasXSfmmWiden(VTypeI) &&
+ RISCVVType::getSEW(VTypeI) * RISCVVType::getXSfmmWiden(VTypeI) <= 64 &&
+ isValidVType(VTypeI);
+}
+
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS);
LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index b937d81bb98cb..b381b8f7147fc 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -223,8 +223,7 @@ void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo,
// Print the raw immediate for reserved values: vlmul[2:0]=4, vsew[2:0]=0b1xx,
// altfmt=1 without zvfbfa or zvfofp8min extension, or non-zero in bits 9 and
// above.
- if (RISCVVType::getVLMUL(Imm) == RISCVVType::VLMUL::LMUL_RESERVED ||
- RISCVVType::getSEW(Imm) > 64 ||
+ if (!RISCVVType::isValidVType(Imm) ||
(RISCVVType::isAltFmt(Imm) &&
!(STI.hasFeature(RISCV::FeatureStdExtZvfbfa) ||
STI.hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 797eebca70952..744a6dc57d521 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -362,18 +362,21 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
RatiolessInfo.setAVL(Info);
Info = RatiolessInfo;
} else {
+ unsigned SEW =
+ ((Demanded.SEW || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
+ .getSEW();
Info.setVTYPE(
((Demanded.LMUL || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
.getVLMUL(),
- ((Demanded.SEW || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
- .getSEW(),
+ SEW,
// Prefer tail/mask agnostic since it can be relaxed to undisturbed
// later if needed.
(Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() ||
IncomingInfo.getTailAgnostic(),
(Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
IncomingInfo.getMaskAgnostic(),
- (Demanded.AltFmt ? IncomingInfo : Info).getAltFmt(),
+ // AltFmt requires SEW < 32.
+ (Demanded.AltFmt ? IncomingInfo : Info).getAltFmt() && SEW < 32,
Demanded.TWiden ? IncomingInfo.getTWiden() : 0);
}
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index ee10d71727c39..cfbb967d89c74 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3085,10 +3085,10 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
Ok = Imm != 0 && isInt<6>(Imm);
break;
case RISCVOp::OPERAND_VTYPEI10:
- Ok = isUInt<10>(Imm);
+ Ok = isUInt<10>(Imm) && RISCVVType::isValidVType(Imm);
break;
case RISCVOp::OPERAND_VTYPEI11:
- Ok = isUInt<11>(Imm);
+ Ok = isUInt<11>(Imm) && RISCVVType::isValidVType(Imm);
break;
case RISCVOp::OPERAND_SIMM12_LSB00000:
Ok = isShiftedInt<7, 5>(Imm);
diff --git a/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll b/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
index ef998be8f1d42..e815e4881357c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/mixed-float-bf16-arith.ll
@@ -175,7 +175,7 @@ define <8 x i64> @test_bf16_i64(<8 x i64> %v, <8 x bfloat> %v2, ptr %p) {
; CHECK-NEXT: vsetvli zero, zero, e16alt, m1, ta, ma
; CHECK-NEXT: vfmv.f.s fa5, v12
; CHECK-NEXT: fmv.w.x fa4, zero
-; CHECK-NEXT: vsetvli zero, zero, e64alt, m4, ta, ma
+; CHECK-NEXT: vsetvli zero, zero, e64, m4, ta, ma
; CHECK-NEXT: vadd.vv v12, v16, v16
; CHECK-NEXT: fcvt.s.bf16 fa5, fa5
; CHECK-NEXT: vadd.vv v8, v8, v12
More information about the llvm-commits
mailing list