[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