[llvm] [RISCV] Preserve independent VTYPE facts across CFG joins (PR #228735)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 09:20:35 PDT 2026


https://github.com/tinfengyu created https://github.com/llvm/llvm-project/pull/228735

RISCVInsertVSETVLI can lose independently useful VTYPE information across CFG joins when incoming paths disagree on AVL/VL. This can lead to redundant vector configuration instructions even when the required VTYPE is already known.

Add a bounded side analysis that tracks VTYPE facts independently of VL/AVL information. Forward dataflow computes VTYPE facts that hold on all incoming paths, while backward dataflow determines whether the VTYPE established by a candidate configuration is needed before it is overwritten or observed. The analysis deliberately does not infer a common VL from a common VTYPE.

The optimization remains conservative around unsupported or potentially observable operations. Candidate instructions are collected before mutation and removed separately, after which physical VL/VTYPE liveness and analysis state are repaired.

Tests cover independent VTYPE facts across CFG joins, differing AVL provenance, cases where a common VTYPE must not be treated as a common VL, and existing RVV cases affected by the generated-code changes. The focused and affected RISC-V tests pass with the final patch.

AI tool usage: AI tools assisted with the implementation and tests. I reviewed and validated the implementation, tests, and generated changes and take responsibility for the contribution.

>From 75b7f657df487158f42bddc15d5a6c8207b3aaee Mon Sep 17 00:00:00 2001
From: tinfeng <1768309929 at qq.com>
Date: Sat, 3 Oct 2026 22:14:04 +0800
Subject: [PATCH] [RISCV] Preserve independent VTYPE facts across CFG joins

Incoming paths can disagree on AVL provenance while retaining useful legal
VTYPE facts. Preserve those facts in a bounded cleanup of the final
RISCVInsertVSETVLI stream, without inferring common VL from common VTYPE.

Use forward must-facts and backward observer demands to remove redundant
AVL1 setups for integer scalar extraction and guaranteed whole-register
copies. Collect independent deletion proofs before mutation and maintain
physical state liveness and available instruction-index analyses.
---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp  |  557 ++++++++
 .../RISCV/rvv/fixed-vectors-masked-gather.ll  |  272 ++--
 .../RISCV/rvv/vp-vector-interleaved-access.ll |    5 +-
 .../rvv/vsetvli-independent-type-facts.ll     |  390 ++++++
 .../rvv/vsetvli-independent-type-facts.mir    | 1243 +++++++++++++++++
 5 files changed, 2328 insertions(+), 139 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.ll
 create mode 100644 llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.mir

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 1087737e2d96ca..b67c01ae174e4d 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -27,12 +27,15 @@
 #include "RISCV.h"
 #include "RISCVSubtarget.h"
 #include "RISCVVSETVLIInfoAnalysis.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/LiveDebugVariables.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/LiveStacks.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include <optional>
 #include <queue>
 using namespace llvm;
 using namespace RISCV;
@@ -43,6 +46,21 @@ using namespace RISCV;
 STATISTIC(NumInsertedVSETVL, "Number of VSETVL inst inserted");
 STATISTIC(NumCoalescedVSETVL, "Number of VSETVL inst coalesced");
 
+STATISTIC(NumIndependentVTYPECandidates, "Number of optional type-only setups");
+STATISTIC(NumIndependentVTYPEBlocks, "Number of blocks in type-fact cleanup");
+STATISTIC(NumIndependentVTYPEForwardVisits,
+          "Number of forward type-fact worklist visits");
+STATISTIC(NumIndependentVTYPEBackwardVisits,
+          "Number of backward type-safety worklist visits");
+STATISTIC(NumIndependentVTYPEInstructionScans,
+          "Number of instructions scanned by type-fact worklists");
+STATISTIC(NumIndependentVTYPEDeleted,
+          "Number of independently redundant type-only setups deleted");
+
+static cl::opt<bool> EnableIndependentVTYPEFacts(
+    DEBUG_TYPE "-independent-type-facts", cl::Hidden, cl::init(true),
+    cl::desc("Remove redundant vector setups using independent type facts"));
+
 static cl::opt<bool> EnsureWholeVectorRegisterMoveValidVTYPE(
     DEBUG_TYPE "-whole-vector-register-move-valid-vtype", cl::Hidden,
     cl::desc("Insert vsetvlis before vmvNr.vs to ensure vtype is valid and "
@@ -88,6 +106,531 @@ enum TKTMMode {
   VSETTM = 1,
 };
 
+// Common type facts describe fixed, final MIR. They intentionally say nothing
+// about AVL, the selected VL, or whether VL is zero.
+struct IndependentVTYPEFact {
+  enum Kind { NotReached, Exact, Clear, Unknown } K = NotReached;
+  unsigned Encoding = 0;
+
+  bool operator==(const IndependentVTYPEFact &Other) const {
+    return K == Other.K && (K != Exact || Encoding == Other.Encoding);
+  }
+
+  IndependentVTYPEFact merge(IndependentVTYPEFact Other) const {
+    if (K == NotReached)
+      return Other;
+    if (Other.K == NotReached || *this == Other)
+      return *this;
+    if (K == Unknown || Other.K == Unknown)
+      return {Unknown};
+    return {Clear};
+  }
+};
+
+// This deliberately excludes explicit architectural-state manipulation. Check
+// both the original stream (before configs are inserted) and the final stream.
+static bool hasIndependentVTYPEFactScope(const MachineFunction &MF,
+                                         const RISCVSubtarget &ST,
+                                         bool BeforeInsertion) {
+  if (ST.hasVendorXSfmmbase())
+    return false;
+  for (const MachineBasicBlock &MBB : MF)
+    for (const MachineInstr &MI : MBB) {
+      if (MI.isBundled() || MI.isCall() || MI.isInlineAsm() ||
+          RISCVInstrInfo::isFaultOnlyFirstLoad(MI) ||
+          RISCVInstrInfo::isXSfmmVectorConfigInstr(MI) ||
+          (MI.hasUnmodeledSideEffects() && !MI.isMetaInstruction() &&
+           MI.getOpcode() != RISCV::PseudoRET && !MI.isBranch()))
+        return false;
+      switch (MI.getOpcode()) {
+      case RISCV::CSRRW:
+      case RISCV::CSRRS:
+      case RISCV::CSRRC:
+      case RISCV::CSRRWI:
+      case RISCV::CSRRSI:
+      case RISCV::CSRRCI:
+      case RISCV::ECALL:
+      case RISCV::EBREAK:
+      case RISCV::VSETVLI:
+      case RISCV::VSETIVLI:
+      case RISCV::VSETVL:
+      case RISCV::PseudoReadVL:
+      case RISCV::PseudoReadVLENBViaVSETVLIX0:
+        return false;
+      }
+      bool Config = RISCVInstrInfo::isVectorConfigInstr(MI);
+      if (BeforeInsertion && Config)
+        return false;
+      uint64_t Flags = MI.getDesc().TSFlags;
+      if (RISCVII::hasTWidenOp(Flags) ||
+          RISCVII::getAltFmtType(Flags) == RISCVII::AltFmtType::AltFmt)
+        return false;
+      for (const MachineOperand &MO : MI.operands()) {
+        if (MO.isRegMask())
+          return false;
+        if (!MO.isReg() ||
+            (MO.getReg() != RISCV::VL && MO.getReg() != RISCV::VTYPE))
+          continue;
+        if (!MO.isImplicit() || MO.getSubReg())
+          return false;
+        if (Config)
+          continue; // Config operand shapes are checked by the decoder.
+        if (MO.isDef())
+          return false;
+        if (!RISCVII::hasSEWOp(Flags) &&
+            !RISCV::isVectorCopy(ST.getRegisterInfo(), MI))
+          return false;
+        if (MO.getReg() == RISCV::VL && !RISCVII::hasVLOp(Flags))
+          return false;
+      }
+    }
+  return true;
+}
+
+class IndependentVTYPECleanup {
+  MachineFunction &MF;
+  const RISCVSubtarget &ST;
+  const TargetRegisterInfo &TRI;
+  MachineRegisterInfo &MRI;
+  LiveIntervals *LIS;
+  SmallPtrSet<const MachineInstr *, 32> Optional;
+  SmallPtrSet<const MachineInstr *, 32> WholeCopies;
+
+  bool isLegalType(int64_t Encoding) const {
+    if (Encoding < 0 || (Encoding & ~0xff) ||
+        RISCVVType::getVLMUL(Encoding) != RISCVVType::LMUL_1)
+      return false;
+    unsigned SEW = RISCVVType::getSEW(Encoding);
+    return SEW == 8 || SEW == 16 || SEW == 32 ||
+           (SEW == 64 && ST.hasVInstructionsI64());
+  }
+
+  // Require the ordinary independent overwrite shape, including exactly its
+  // two architectural state defs. x0,x0 is deliberately not an overwrite.
+  std::optional<unsigned> decodeConfig(const MachineInstr &MI) const {
+    unsigned Opcode = MI.getOpcode();
+    if (Opcode != RISCV::PseudoVSETIVLI && Opcode != RISCV::PseudoVSETVLI &&
+        Opcode != RISCV::PseudoVSETVLIX0)
+      return std::nullopt;
+    if (MI.getNumOperands() != 5 || MI.getNumExplicitOperands() != 3 ||
+        !MI.getOperand(0).isReg() || !MI.getOperand(0).isDef() ||
+        MI.getOperand(0).getSubReg() || !isGPR(MI.getOperand(0).getReg()) ||
+        !MI.getOperand(2).isImm() || !isLegalType(MI.getOperand(2).getImm()))
+      return std::nullopt;
+    const MachineOperand &AVL = MI.getOperand(1);
+    if (Opcode == RISCV::PseudoVSETIVLI) {
+      if (!AVL.isImm() || AVL.getImm() < 0 || AVL.getImm() > 31)
+        return std::nullopt;
+    } else if (!AVL.isReg() || !AVL.isUse() || AVL.getSubReg() ||
+               (Opcode == RISCV::PseudoVSETVLIX0
+                    ? AVL.getReg() != RISCV::X0
+                    : !isGPR(AVL.getReg()) || AVL.getReg() == RISCV::X0)) {
+      return std::nullopt;
+    }
+    bool VLDef = false, VTypeDef = false;
+    for (const MachineOperand &MO : MI.implicit_operands()) {
+      if (!MO.isReg() || !MO.isDef() || MO.getSubReg())
+        return std::nullopt;
+      if (MO.getReg() == RISCV::VL && !VLDef)
+        VLDef = true;
+      else if (MO.getReg() == RISCV::VTYPE && !VTypeDef)
+        VTypeDef = true;
+      else
+        return std::nullopt;
+    }
+    if (!VLDef || !VTypeDef)
+      return std::nullopt;
+    return MI.getOperand(2).getImm();
+  }
+
+  bool isGPR(Register Reg) const {
+    if (!Reg)
+      return false;
+    if (Reg.isPhysical())
+      return RISCV::GPRRegClass.contains(Reg);
+    return RISCV::GPRRegClass.hasSubClassEq(MRI.getRegClass(Reg));
+  }
+
+  bool hasWholeCopyShape(const MachineInstr &MI) const {
+    if (!RISCV::isVectorCopy(&TRI, MI) || MI.getNumExplicitOperands() != 2 ||
+        MI.getNumOperands() != 3)
+      return false;
+    for (unsigned I = 0; I != 2; ++I) {
+      const MachineOperand &MO = MI.getOperand(I);
+      if (!MO.isReg() || !MO.getReg().isPhysical() || MO.getSubReg() ||
+          MO.isDef() != (I == 0))
+        return false;
+    }
+    const MachineOperand &State = MI.getOperand(2);
+    if (!State.isReg() || !State.isImplicit() || !State.isUse() ||
+        State.getReg() != RISCV::VTYPE || State.getSubReg())
+      return false;
+    return true;
+  }
+
+  bool isWholeCopy(const MachineInstr &MI) const {
+    return WholeCopies.contains(&MI);
+  }
+
+  bool isExtract(const MachineInstr &MI) const {
+    if (MI.getOpcode() != RISCV::PseudoVMV_X_S ||
+        MI.getNumExplicitOperands() != 3 || MI.getNumOperands() != 4)
+      return false;
+    const MachineOperand &Use = MI.getOperand(3);
+    return Use.isReg() && Use.isImplicit() && Use.isUse() &&
+           Use.getReg() == RISCV::VTYPE && !Use.getSubReg();
+  }
+
+  // Requirements of every suffix path before a retained overwrite or return.
+  enum class Demand {
+    None,
+    LegalOnly,
+    Unsafe,
+    SEW8 = 8,
+    SEW16 = 16,
+    SEW32 = 32,
+    SEW64 = 64
+  };
+
+  static Demand mergeDemand(Demand A, Demand B) {
+    if (A == B || B == Demand::None)
+      return A;
+    if (A == Demand::None)
+      return B;
+    if (A == Demand::Unsafe || B == Demand::Unsafe)
+      return Demand::Unsafe;
+    if (A == Demand::LegalOnly)
+      return B;
+    if (B == Demand::LegalOnly)
+      return A;
+    return Demand::Unsafe; // Distinct exact SEW requirements cannot both hold.
+  }
+
+  static bool accepts(Demand Required, IndependentVTYPEFact Fact) {
+    if (Fact.K != IndependentVTYPEFact::Exact &&
+        Fact.K != IndependentVTYPEFact::Clear)
+      return false;
+    if (Required == Demand::None || Required == Demand::LegalOnly)
+      return true;
+    if (Required == Demand::Unsafe)
+      return false;
+    return Fact.K == IndependentVTYPEFact::Exact &&
+           RISCVVType::getSEW(Fact.Encoding) == static_cast<unsigned>(Required);
+  }
+
+  bool isNeutral(const MachineInstr &MI) const {
+    if (MI.isMetaInstruction())
+      return true;
+    if (MI.hasUnmodeledSideEffects() || MI.mayLoadOrStore())
+      return false;
+    switch (MI.getOpcode()) {
+    case TargetOpcode::COPY:
+    case RISCV::ADD:
+    case RISCV::ADDI:
+    case RISCV::ADDW:
+    case RISCV::ADDIW:
+    case RISCV::SUB:
+    case RISCV::SUBW:
+    case RISCV::AND:
+    case RISCV::ANDI:
+    case RISCV::OR:
+    case RISCV::ORI:
+    case RISCV::XOR:
+    case RISCV::XORI:
+    case RISCV::SLL:
+    case RISCV::SLLI:
+    case RISCV::SRL:
+    case RISCV::SRLI:
+    case RISCV::SRA:
+    case RISCV::SRAI:
+    case RISCV::SLT:
+    case RISCV::SLTI:
+    case RISCV::SLTU:
+    case RISCV::SLTIU:
+    case RISCV::LUI:
+    case RISCV::BEQ:
+    case RISCV::BNE:
+    case RISCV::BLT:
+    case RISCV::BGE:
+    case RISCV::BLTU:
+    case RISCV::BGEU:
+    case RISCV::PseudoBR:
+      break;
+    default:
+      return false;
+    }
+    for (const MachineOperand &MO : MI.operands())
+      if (MO.isRegMask() || (MO.isReg() && !isGPR(MO.getReg())))
+        return false;
+    return true;
+  }
+
+  Demand demandBefore(const MachineInstr &MI, Demand After) const {
+    if (Optional.contains(&MI))
+      return After; // Optional overwrites must never shield an observer.
+    if (decodeConfig(MI))
+      return Demand::None;
+    DemandedFields Used = getDemanded(MI, &ST);
+    if (Used.usedVL())
+      return Demand::Unsafe;
+    if (MI.getOpcode() == RISCV::PseudoRET) {
+      if (Used.usedVTYPE() || !MI.getParent()->succ_empty() ||
+          MI.getNumExplicitOperands())
+        return Demand::Unsafe;
+      for (const MachineOperand &MO : MI.operands()) {
+        if (!MO.isReg() || !MO.isImplicit() || !MO.isUse() ||
+            !MO.getReg().isPhysical() || MO.getSubReg())
+          return Demand::Unsafe;
+        Register Reg = MO.getReg();
+        if (!RISCV::GPRRegClass.contains(Reg) &&
+            !RISCV::FPR16RegClass.contains(Reg) &&
+            !RISCV::FPR32RegClass.contains(Reg) &&
+            !RISCV::FPR64RegClass.contains(Reg) &&
+            !RISCV::VRRegClass.contains(Reg) &&
+            !RISCV::VRM2RegClass.contains(Reg) &&
+            !RISCV::VRM4RegClass.contains(Reg) &&
+            !RISCV::VRM8RegClass.contains(Reg))
+          return Demand::Unsafe;
+      }
+      return Demand::None;
+    }
+    if (isWholeCopy(MI) && !Used.SEW && !Used.LMUL && !Used.SEWLMULRatio &&
+        !Used.TailPolicy && !Used.MaskPolicy && !Used.AltFmt && !Used.TWiden)
+      return mergeDemand(Demand::LegalOnly, After);
+    if (isExtract(MI)) {
+      // Keep the required-type support certificate and explicitly check the
+      // integer extraction contract before summarizing compatibility as SEW.
+      if (Used.SEW != DemandedFields::SEWEqual ||
+          Used.LMUL != DemandedFields::LMULNone || Used.SEWLMULRatio ||
+          Used.TailPolicy || Used.MaskPolicy || Used.AltFmt || Used.TWiden)
+        return Demand::Unsafe;
+      RISCVVSETVLIInfoAnalysis Requirements(&ST, nullptr);
+      unsigned Required = Requirements.computeInfoForInstr(MI).encodeVTYPE();
+      if (!isLegalType(Required))
+        return Demand::Unsafe;
+      return mergeDemand(static_cast<Demand>(RISCVVType::getSEW(Required)),
+                         After);
+    }
+    return !Used.usedVTYPE() && isNeutral(MI) ? After : Demand::Unsafe;
+  }
+
+  IndependentVTYPEFact transfer(const MachineInstr &MI,
+                                IndependentVTYPEFact Fact) const {
+    if (Fact.K == IndependentVTYPEFact::NotReached)
+      return Fact;
+    if (Optional.contains(&MI))
+      return {IndependentVTYPEFact::Unknown};
+    if (auto Encoding = decodeConfig(MI))
+      return {IndependentVTYPEFact::Exact, *Encoding};
+    if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
+        MI.modifiesRegister(RISCV::VTYPE, &TRI))
+      return {IndependentVTYPEFact::Unknown};
+    return Fact;
+  }
+
+public:
+  IndependentVTYPECleanup(MachineFunction &MF, const RISCVSubtarget &ST,
+                          LiveIntervals *LIS)
+      : MF(MF), ST(ST), TRI(*ST.getRegisterInfo()), MRI(MF.getRegInfo()),
+        LIS(LIS) {}
+
+  void run(SlotIndexes *Indexes) {
+    // The downstream COPY converter searches for an explicit local producer.
+    // Track physical defs once per block; this check is bounded by the number
+    // of target registers, rather than rescanning a prefix for every COPY.
+    for (MachineBasicBlock &MBB : MF) {
+      SmallSet<Register, 32> Defined;
+      for (MachineInstr &MI : MBB) {
+        if (MI.isMetaInstruction())
+          continue;
+        if (hasWholeCopyShape(MI)) {
+          Register Source = MI.getOperand(1).getReg();
+          if (llvm::none_of(Defined, [&](Register Def) {
+                return TRI.regsOverlap(Def, Source);
+              }))
+            WholeCopies.insert(&MI);
+        }
+        for (const MachineOperand &MO : MI.explicit_operands())
+          if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical())
+            Defined.insert(MO.getReg());
+      }
+    }
+    // Freeze this set before either analysis. Even a retained Optional kills
+    // forward facts and is transparent to backward safety.
+    for (MachineBasicBlock &MBB : MF)
+      for (MachineInstr &MI : MBB) {
+        if (MI.getOpcode() != RISCV::PseudoVSETIVLI || !decodeConfig(MI) ||
+            MI.getOperand(0).getReg() != RISCV::X0 ||
+            !MI.getOperand(0).isDead() || MI.getOperand(1).getImm() != 1)
+          continue;
+        auto Next = std::next(MI.getIterator());
+        while (Next != MBB.end() && Next->isMetaInstruction())
+          ++Next;
+        if (Next != MBB.end() && (isExtract(*Next) || isWholeCopy(*Next)))
+          Optional.insert(&MI);
+      }
+    if (Optional.empty())
+      return;
+    NumIndependentVTYPECandidates += Optional.size();
+    NumIndependentVTYPEBlocks += MF.size();
+
+    unsigned N = MF.getNumBlockIDs();
+    SmallVector<IndependentVTYPEFact> Entries(N), Exits(N);
+    SmallVector<MachineBasicBlock *> Queue;
+    BitVector Queued(N);
+    auto Enqueue = [&](MachineBasicBlock *MBB) {
+      if (!Queued.test(MBB->getNumber())) {
+        Queued.set(MBB->getNumber());
+        Queue.push_back(MBB);
+      }
+    };
+    Enqueue(&MF.front());
+    while (!Queue.empty()) {
+      MachineBasicBlock &MBB = *Queue.pop_back_val();
+      Queued.reset(MBB.getNumber());
+      ++NumIndependentVTYPEForwardVisits;
+      IndependentVTYPEFact Entry;
+      if (&MBB == &MF.front())
+        Entry.K = IndependentVTYPEFact::Unknown;
+      for (MachineBasicBlock *Pred : MBB.predecessors())
+        Entry = Entry.merge(Exits[Pred->getNumber()]);
+      Entries[MBB.getNumber()] = Entry;
+      IndependentVTYPEFact Exit = Entry;
+      for (const MachineInstr &MI : MBB) {
+        ++NumIndependentVTYPEInstructionScans;
+        Exit = transfer(MI, Exit);
+      }
+      if (Exit == Exits[MBB.getNumber()])
+        continue;
+      Exits[MBB.getNumber()] = Exit;
+      for (MachineBasicBlock *Succ : MBB.successors())
+        Enqueue(Succ);
+    }
+
+    // Least fixed point: closed neutral cycles require nothing; observers
+    // strengthen demands and a bad observer on any path propagates Unsafe.
+    SmallVector<Demand> DemandEntry(N, Demand::None),
+        DemandExit(N, Demand::None);
+    Queue.clear();
+    Queued.reset();
+    for (MachineBasicBlock &MBB : MF)
+      Enqueue(&MBB);
+    while (!Queue.empty()) {
+      MachineBasicBlock &MBB = *Queue.pop_back_val();
+      Queued.reset(MBB.getNumber());
+      ++NumIndependentVTYPEBackwardVisits;
+      Demand Required = MBB.succ_empty() ? Demand::Unsafe : Demand::None;
+      for (MachineBasicBlock *Succ : MBB.successors())
+        Required = mergeDemand(Required, DemandEntry[Succ->getNumber()]);
+      DemandExit[MBB.getNumber()] = Required;
+      for (const MachineInstr &MI : llvm::reverse(MBB)) {
+        ++NumIndependentVTYPEInstructionScans;
+        Required = demandBefore(MI, Required);
+      }
+      if (Required == DemandEntry[MBB.getNumber()])
+        continue;
+      DemandEntry[MBB.getNumber()] = Required;
+      for (MachineBasicBlock *Pred : MBB.predecessors())
+        Enqueue(Pred);
+    }
+
+    // Pair each candidate's suffix demand AFTER the Optional with the forward
+    // fact BEFORE it. Both analyses use the immutable original instruction set.
+    DenseMap<const MachineInstr *, Demand> SuffixDemand;
+    for (MachineBasicBlock &MBB : MF) {
+      Demand Required = DemandExit[MBB.getNumber()];
+      for (const MachineInstr &MI : llvm::reverse(MBB)) {
+        if (Optional.contains(&MI))
+          SuffixDemand[&MI] = Required;
+        Required = demandBefore(MI, Required);
+      }
+    }
+    SmallVector<MachineInstr *> Remove;
+    for (MachineBasicBlock &MBB : MF) {
+      IndependentVTYPEFact Fact = Entries[MBB.getNumber()];
+      for (MachineInstr &MI : MBB) {
+        auto It = SuffixDemand.find(&MI);
+        if (It != SuffixDemand.end() && accepts(It->second, Fact))
+          Remove.push_back(&MI);
+        Fact = transfer(MI, Fact);
+      }
+    }
+
+    // No mutations until every proof has been selected. A deletion never
+    // creates facts for another deletion in this invocation.
+    if (Remove.empty())
+      return;
+    for (MachineInstr *MI : Remove) {
+      if (LIS)
+        LIS->RemoveMachineInstrFromMaps(*MI);
+      else if (Indexes)
+        Indexes->removeMachineInstrFromMaps(*MI);
+      MI->eraseFromParent();
+      ++NumIndependentVTYPEDeleted;
+    }
+    // Recompute just the two affected physical live-in sets. Deleted defs can
+    // expose uses across joins and through otherwise transparent blocks.
+    SmallVector<unsigned> LiveIn(N, 0);
+    Queue.clear();
+    Queued.reset();
+    for (MachineBasicBlock &MBB : MF)
+      Enqueue(&MBB);
+    while (!Queue.empty()) {
+      MachineBasicBlock &MBB = *Queue.pop_back_val();
+      Queued.reset(MBB.getNumber());
+      unsigned Live = 0;
+      for (MachineBasicBlock *Succ : MBB.successors())
+        Live |= LiveIn[Succ->getNumber()];
+      for (const MachineInstr &MI : llvm::reverse(MBB)) {
+        for (const MachineOperand &MO : MI.operands()) {
+          if (!MO.isReg() || !MO.isDef())
+            continue;
+          if (MO.getReg() == RISCV::VL)
+            Live &= ~1U;
+          if (MO.getReg() == RISCV::VTYPE)
+            Live &= ~2U;
+        }
+        for (const MachineOperand &MO : MI.operands()) {
+          if (!MO.isReg() || !MO.isUse() || MO.isUndef())
+            continue;
+          if (MO.getReg() == RISCV::VL)
+            Live |= 1;
+          if (MO.getReg() == RISCV::VTYPE)
+            Live |= 2;
+        }
+      }
+      if (Live == LiveIn[MBB.getNumber()])
+        continue;
+      LiveIn[MBB.getNumber()] = Live;
+      for (MachineBasicBlock *Pred : MBB.predecessors())
+        Enqueue(Pred);
+    }
+    for (MachineBasicBlock &MBB : MF) {
+      for (auto [Reg, Mask] :
+           {std::pair(RISCV::VL, 1U), std::pair(RISCV::VTYPE, 2U)}) {
+        MBB.removeLiveIn(Reg);
+        if (LiveIn[MBB.getNumber()] & Mask)
+          MBB.addLiveIn(Reg);
+      }
+      MBB.sortUniqueLiveIns();
+    }
+    if (LIS) {
+      LIS->removeAllRegUnitsForPhysReg(RISCV::VL);
+      LIS->removeAllRegUnitsForPhysReg(RISCV::VTYPE);
+    }
+    for (MachineBasicBlock &MBB : MF)
+      for (MachineInstr &MI : MBB)
+        for (MachineOperand &MO : MI.operands())
+          if (MO.isReg() &&
+              (MO.getReg() == RISCV::VL || MO.getReg() == RISCV::VTYPE)) {
+            if (MO.isDef())
+              MO.setIsDead(false);
+            else
+              MO.setIsKill(false);
+          }
+  }
+};
+
 class RISCVInsertVSETVLI : public MachineFunctionPass {
   const RISCVSubtarget *ST;
   const TargetInstrInfo *TII;
@@ -109,6 +652,7 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
     AU.setPreservesCFG();
 
     AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
+    AU.addUsedIfAvailable<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveIntervalsWrapperPass>();
     AU.addPreserved<SlotIndexesWrapperPass>();
     AU.addPreserved<LiveDebugVariablesWrapperLegacy>();
@@ -1146,6 +1690,10 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
   LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
   VIA = RISCVVSETVLIInfoAnalysis(ST, LIS);
 
+  bool IndependentTypeScope =
+      EnableIndependentVTYPEFacts &&
+      hasIndependentVTYPEFactScope(MF, *ST, /*BeforeInsertion=*/true);
+
   assert(BlockInfo.empty() && "Expect empty block infos");
   BlockInfo.resize(MF.getNumBlockIDs());
 
@@ -1222,6 +1770,15 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
     }
   }
 
+  // These facts describe the fixed emitted stream. No earlier insertion,
+  // coalescing, PRE, or scheduler query consumes partial configuration state.
+  if (IndependentTypeScope &&
+      hasIndependentVTYPEFactScope(MF, *ST, /*BeforeInsertion=*/false)) {
+    auto *IndexesWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
+    IndependentVTYPECleanup(MF, *ST, LIS)
+        .run(IndexesWrapper ? &IndexesWrapper->getSI() : nullptr);
+  }
+
   BlockInfo.clear();
   return HaveVectorOp;
 }
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll
index 1baa2a14cf57c8..2921d3e74058a1 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll
@@ -1868,13 +1868,13 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vmv.x.s a1, v0
 ; RV64ZVE32F-NEXT:    andi a2, a1, 1
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_11
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_10
 ; RV64ZVE32F-NEXT:  # %bb.1: # %else
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_12
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_11
 ; RV64ZVE32F-NEXT:  .LBB26_2: # %else2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_13
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_12
 ; RV64ZVE32F-NEXT:  .LBB26_3: # %else5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB26_5
@@ -1892,31 +1892,20 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vsetivli zero, 4, e16, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 16
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_14
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_13
 ; RV64ZVE32F-NEXT:  # %bb.6: # %else11
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_15
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_14
 ; RV64ZVE32F-NEXT:  .LBB26_7: # %else14
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
-; RV64ZVE32F-NEXT:    bnez a2, .LBB26_16
+; RV64ZVE32F-NEXT:    bnez a2, .LBB26_15
 ; RV64ZVE32F-NEXT:  .LBB26_8: # %else17
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    beqz a1, .LBB26_10
-; RV64ZVE32F-NEXT:  .LBB26_9: # %cond.load19
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
-; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
-; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
-; RV64ZVE32F-NEXT:    slli a1, a1, 1
-; RV64ZVE32F-NEXT:    add a0, a0, a1
-; RV64ZVE32F-NEXT:    lh a0, 0(a0)
-; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
-; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
-; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
-; RV64ZVE32F-NEXT:  .LBB26_10: # %else20
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
+; RV64ZVE32F-NEXT:    bnez a1, .LBB26_16
+; RV64ZVE32F-NEXT:  .LBB26_9: # %else20
 ; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
 ; RV64ZVE32F-NEXT:    ret
-; RV64ZVE32F-NEXT:  .LBB26_11: # %cond.load
+; RV64ZVE32F-NEXT:  .LBB26_10: # %cond.load
 ; RV64ZVE32F-NEXT:    vsetvli zero, zero, e16, m2, tu, ma
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 1
@@ -1925,7 +1914,7 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vmv.s.x v9, a2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB26_2
-; RV64ZVE32F-NEXT:  .LBB26_12: # %cond.load1
+; RV64ZVE32F-NEXT:  .LBB26_11: # %cond.load1
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -1937,7 +1926,7 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 1
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB26_3
-; RV64ZVE32F-NEXT:  .LBB26_13: # %cond.load4
+; RV64ZVE32F-NEXT:  .LBB26_12: # %cond.load4
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -1950,7 +1939,7 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    bnez a2, .LBB26_4
 ; RV64ZVE32F-NEXT:    j .LBB26_5
-; RV64ZVE32F-NEXT:  .LBB26_14: # %cond.load10
+; RV64ZVE32F-NEXT:  .LBB26_13: # %cond.load10
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 1
 ; RV64ZVE32F-NEXT:    add a2, a0, a2
@@ -1960,7 +1949,7 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB26_7
-; RV64ZVE32F-NEXT:  .LBB26_15: # %cond.load13
+; RV64ZVE32F-NEXT:  .LBB26_14: # %cond.load13
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -1972,7 +1961,7 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB26_8
-; RV64ZVE32F-NEXT:  .LBB26_16: # %cond.load16
+; RV64ZVE32F-NEXT:  .LBB26_15: # %cond.load16
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -1983,8 +1972,19 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m,
 ; RV64ZVE32F-NEXT:    vsetivli zero, 7, e16, m1, tu, ma
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 6
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    bnez a1, .LBB26_9
-; RV64ZVE32F-NEXT:    j .LBB26_10
+; RV64ZVE32F-NEXT:    beqz a1, .LBB26_9
+; RV64ZVE32F-NEXT:  .LBB26_16: # %cond.load19
+; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
+; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
+; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
+; RV64ZVE32F-NEXT:    slli a1, a1, 1
+; RV64ZVE32F-NEXT:    add a0, a0, a1
+; RV64ZVE32F-NEXT:    lh a0, 0(a0)
+; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
+; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
+; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
+; RV64ZVE32F-NEXT:    ret
   %ptrs = getelementptr inbounds i16, ptr %base, <8 x i16> %idxs
   %v = call <8 x i16> @llvm.masked.gather.v8i16.v8p0(<8 x ptr> %ptrs, i32 2, <8 x i1> %m, <8 x i16> %passthru)
   ret <8 x i16> %v
@@ -7779,13 +7779,13 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vmv.x.s a1, v0
 ; RV64ZVE32F-NEXT:    andi a2, a1, 1
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_11
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_10
 ; RV64ZVE32F-NEXT:  # %bb.1: # %else
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_12
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_11
 ; RV64ZVE32F-NEXT:  .LBB67_2: # %else2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_13
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_12
 ; RV64ZVE32F-NEXT:  .LBB67_3: # %else5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB67_5
@@ -7803,31 +7803,20 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vsetivli zero, 4, e16, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 16
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_14
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_13
 ; RV64ZVE32F-NEXT:  # %bb.6: # %else11
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_15
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_14
 ; RV64ZVE32F-NEXT:  .LBB67_7: # %else14
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
-; RV64ZVE32F-NEXT:    bnez a2, .LBB67_16
+; RV64ZVE32F-NEXT:    bnez a2, .LBB67_15
 ; RV64ZVE32F-NEXT:  .LBB67_8: # %else17
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    beqz a1, .LBB67_10
-; RV64ZVE32F-NEXT:  .LBB67_9: # %cond.load19
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
-; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
-; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
-; RV64ZVE32F-NEXT:    slli a1, a1, 1
-; RV64ZVE32F-NEXT:    add a0, a0, a1
-; RV64ZVE32F-NEXT:    lh a0, 0(a0)
-; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
-; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
-; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
-; RV64ZVE32F-NEXT:  .LBB67_10: # %else20
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
+; RV64ZVE32F-NEXT:    bnez a1, .LBB67_16
+; RV64ZVE32F-NEXT:  .LBB67_9: # %else20
 ; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
 ; RV64ZVE32F-NEXT:    ret
-; RV64ZVE32F-NEXT:  .LBB67_11: # %cond.load
+; RV64ZVE32F-NEXT:  .LBB67_10: # %cond.load
 ; RV64ZVE32F-NEXT:    vsetvli zero, zero, e16, m2, tu, ma
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 1
@@ -7836,7 +7825,7 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vmv.s.x v9, a2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB67_2
-; RV64ZVE32F-NEXT:  .LBB67_12: # %cond.load1
+; RV64ZVE32F-NEXT:  .LBB67_11: # %cond.load1
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -7848,7 +7837,7 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 1
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB67_3
-; RV64ZVE32F-NEXT:  .LBB67_13: # %cond.load4
+; RV64ZVE32F-NEXT:  .LBB67_12: # %cond.load4
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -7861,7 +7850,7 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    bnez a2, .LBB67_4
 ; RV64ZVE32F-NEXT:    j .LBB67_5
-; RV64ZVE32F-NEXT:  .LBB67_14: # %cond.load10
+; RV64ZVE32F-NEXT:  .LBB67_13: # %cond.load10
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 1
 ; RV64ZVE32F-NEXT:    add a2, a0, a2
@@ -7871,7 +7860,7 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB67_7
-; RV64ZVE32F-NEXT:  .LBB67_15: # %cond.load13
+; RV64ZVE32F-NEXT:  .LBB67_14: # %cond.load13
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -7883,7 +7872,7 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB67_8
-; RV64ZVE32F-NEXT:  .LBB67_16: # %cond.load16
+; RV64ZVE32F-NEXT:  .LBB67_15: # %cond.load16
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -7894,8 +7883,19 @@ define <8 x bfloat> @mgather_baseidx_v8bf16(ptr %base, <8 x i16> %idxs, <8 x i1>
 ; RV64ZVE32F-NEXT:    vsetivli zero, 7, e16, m1, tu, ma
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 6
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    bnez a1, .LBB67_9
-; RV64ZVE32F-NEXT:    j .LBB67_10
+; RV64ZVE32F-NEXT:    beqz a1, .LBB67_9
+; RV64ZVE32F-NEXT:  .LBB67_16: # %cond.load19
+; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
+; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
+; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
+; RV64ZVE32F-NEXT:    slli a1, a1, 1
+; RV64ZVE32F-NEXT:    add a0, a0, a1
+; RV64ZVE32F-NEXT:    lh a0, 0(a0)
+; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
+; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
+; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
+; RV64ZVE32F-NEXT:    ret
   %ptrs = getelementptr inbounds bfloat, ptr %base, <8 x i16> %idxs
   %v = call <8 x bfloat> @llvm.masked.gather.v8bf16.v8p0(<8 x ptr> %ptrs, i32 2, <8 x i1> %m, <8 x bfloat> %passthru)
   ret <8 x bfloat> %v
@@ -9298,13 +9298,13 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a1, v0
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 1
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_11
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_10
 ; RV64ZVE32F-ZVFH-NEXT:  # %bb.1: # %else
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 2
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_12
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_11
 ; RV64ZVE32F-ZVFH-NEXT:  .LBB77_2: # %else2
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 4
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_13
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_12
 ; RV64ZVE32F-ZVFH-NEXT:  .LBB77_3: # %else5
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-ZVFH-NEXT:    beqz a2, .LBB77_5
@@ -9322,31 +9322,20 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 4, e16, m1, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v8, v8, 4
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 16
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_14
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_13
 ; RV64ZVE32F-ZVFH-NEXT:  # %bb.6: # %else11
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 32
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_15
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_14
 ; RV64ZVE32F-ZVFH-NEXT:  .LBB77_7: # %else14
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 64
-; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_16
+; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_15
 ; RV64ZVE32F-ZVFH-NEXT:  .LBB77_8: # %else17
 ; RV64ZVE32F-ZVFH-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-ZVFH-NEXT:    beqz a1, .LBB77_10
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_9: # %cond.load19
-; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
-; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v8, v8, 3
-; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a1, v8
-; RV64ZVE32F-ZVFH-NEXT:    slli a1, a1, 1
-; RV64ZVE32F-ZVFH-NEXT:    add a0, a0, a1
-; RV64ZVE32F-ZVFH-NEXT:    flh fa5, 0(a0)
-; RV64ZVE32F-ZVFH-NEXT:    vfmv.s.f v8, fa5
-; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
-; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v8, 7
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_10: # %else20
-; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
+; RV64ZVE32F-ZVFH-NEXT:    bnez a1, .LBB77_16
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_9: # %else20
 ; RV64ZVE32F-ZVFH-NEXT:    vmv1r.v v8, v9
 ; RV64ZVE32F-ZVFH-NEXT:    ret
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_11: # %cond.load
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_10: # %cond.load
 ; RV64ZVE32F-ZVFH-NEXT:    vsetvli zero, zero, e16, m2, tu, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-ZVFH-NEXT:    slli a2, a2, 1
@@ -9355,7 +9344,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vfmv.s.f v9, fa5
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 2
 ; RV64ZVE32F-ZVFH-NEXT:    beqz a2, .LBB77_2
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_12: # %cond.load1
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_11: # %cond.load1
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v10
@@ -9367,7 +9356,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v10, 1
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 4
 ; RV64ZVE32F-ZVFH-NEXT:    beqz a2, .LBB77_3
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_13: # %cond.load4
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_12: # %cond.load4
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v10
@@ -9380,7 +9369,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-ZVFH-NEXT:    bnez a2, .LBB77_4
 ; RV64ZVE32F-ZVFH-NEXT:    j .LBB77_5
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_14: # %cond.load10
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_13: # %cond.load10
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-ZVFH-NEXT:    slli a2, a2, 1
 ; RV64ZVE32F-ZVFH-NEXT:    add a2, a0, a2
@@ -9390,7 +9379,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v10, 4
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 32
 ; RV64ZVE32F-ZVFH-NEXT:    beqz a2, .LBB77_7
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_15: # %cond.load13
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_14: # %cond.load13
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v10
@@ -9402,7 +9391,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v10, 5
 ; RV64ZVE32F-ZVFH-NEXT:    andi a2, a1, 64
 ; RV64ZVE32F-ZVFH-NEXT:    beqz a2, .LBB77_8
-; RV64ZVE32F-ZVFH-NEXT:  .LBB77_16: # %cond.load16
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_15: # %cond.load16
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a2, v10
@@ -9413,21 +9402,32 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 7, e16, m1, tu, ma
 ; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v10, 6
 ; RV64ZVE32F-ZVFH-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-ZVFH-NEXT:    bnez a1, .LBB77_9
-; RV64ZVE32F-ZVFH-NEXT:    j .LBB77_10
+; RV64ZVE32F-ZVFH-NEXT:    beqz a1, .LBB77_9
+; RV64ZVE32F-ZVFH-NEXT:  .LBB77_16: # %cond.load19
+; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
+; RV64ZVE32F-ZVFH-NEXT:    vslidedown.vi v8, v8, 3
+; RV64ZVE32F-ZVFH-NEXT:    vmv.x.s a1, v8
+; RV64ZVE32F-ZVFH-NEXT:    slli a1, a1, 1
+; RV64ZVE32F-ZVFH-NEXT:    add a0, a0, a1
+; RV64ZVE32F-ZVFH-NEXT:    flh fa5, 0(a0)
+; RV64ZVE32F-ZVFH-NEXT:    vfmv.s.f v8, fa5
+; RV64ZVE32F-ZVFH-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; RV64ZVE32F-ZVFH-NEXT:    vslideup.vi v9, v8, 7
+; RV64ZVE32F-ZVFH-NEXT:    vmv1r.v v8, v9
+; RV64ZVE32F-ZVFH-NEXT:    ret
 ;
 ; RV64ZVE32F-ZVFHMIN-LABEL: mgather_baseidx_v8f16:
 ; RV64ZVE32F-ZVFHMIN:       # %bb.0:
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a1, v0
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 1
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_11
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_10
 ; RV64ZVE32F-ZVFHMIN-NEXT:  # %bb.1: # %else
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 2
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_12
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_11
 ; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_2: # %else2
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 4
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_13
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_12
 ; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_3: # %else5
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a2, .LBB77_5
@@ -9445,31 +9445,20 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 4, e16, m1, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v8, v8, 4
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 16
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_14
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_13
 ; RV64ZVE32F-ZVFHMIN-NEXT:  # %bb.6: # %else11
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 32
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_15
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_14
 ; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_7: # %else14
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 64
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_16
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_15
 ; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_8: # %else17
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a1, .LBB77_10
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_9: # %cond.load19
-; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
-; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v8, v8, 3
-; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a1, v8
-; RV64ZVE32F-ZVFHMIN-NEXT:    slli a1, a1, 1
-; RV64ZVE32F-ZVFHMIN-NEXT:    add a0, a0, a1
-; RV64ZVE32F-ZVFHMIN-NEXT:    lh a0, 0(a0)
-; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.s.x v8, a0
-; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
-; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v8, 7
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_10: # %else20
-; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
+; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a1, .LBB77_16
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_9: # %else20
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv1r.v v8, v9
 ; RV64ZVE32F-ZVFHMIN-NEXT:    ret
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_11: # %cond.load
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_10: # %cond.load
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetvli zero, zero, e16, m2, tu, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-ZVFHMIN-NEXT:    slli a2, a2, 1
@@ -9478,7 +9467,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.s.x v9, a2
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 2
 ; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a2, .LBB77_2
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_12: # %cond.load1
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_11: # %cond.load1
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v10
@@ -9490,7 +9479,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v10, 1
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 4
 ; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a2, .LBB77_3
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_13: # %cond.load4
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_12: # %cond.load4
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v10
@@ -9503,7 +9492,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a2, .LBB77_4
 ; RV64ZVE32F-ZVFHMIN-NEXT:    j .LBB77_5
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_14: # %cond.load10
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_13: # %cond.load10
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-ZVFHMIN-NEXT:    slli a2, a2, 1
 ; RV64ZVE32F-ZVFHMIN-NEXT:    add a2, a0, a2
@@ -9513,7 +9502,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v10, 4
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 32
 ; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a2, .LBB77_7
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_15: # %cond.load13
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_14: # %cond.load13
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v10
@@ -9525,7 +9514,7 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v10, 5
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a2, a1, 64
 ; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a2, .LBB77_8
-; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_16: # %cond.load16
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_15: # %cond.load16
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a2, v10
@@ -9536,8 +9525,19 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 7, e16, m1, tu, ma
 ; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v10, 6
 ; RV64ZVE32F-ZVFHMIN-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-ZVFHMIN-NEXT:    bnez a1, .LBB77_9
-; RV64ZVE32F-ZVFHMIN-NEXT:    j .LBB77_10
+; RV64ZVE32F-ZVFHMIN-NEXT:    beqz a1, .LBB77_9
+; RV64ZVE32F-ZVFHMIN-NEXT:  .LBB77_16: # %cond.load19
+; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
+; RV64ZVE32F-ZVFHMIN-NEXT:    vslidedown.vi v8, v8, 3
+; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.x.s a1, v8
+; RV64ZVE32F-ZVFHMIN-NEXT:    slli a1, a1, 1
+; RV64ZVE32F-ZVFHMIN-NEXT:    add a0, a0, a1
+; RV64ZVE32F-ZVFHMIN-NEXT:    lh a0, 0(a0)
+; RV64ZVE32F-ZVFHMIN-NEXT:    vmv.s.x v8, a0
+; RV64ZVE32F-ZVFHMIN-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; RV64ZVE32F-ZVFHMIN-NEXT:    vslideup.vi v9, v8, 7
+; RV64ZVE32F-ZVFHMIN-NEXT:    vmv1r.v v8, v9
+; RV64ZVE32F-ZVFHMIN-NEXT:    ret
   %ptrs = getelementptr inbounds half, ptr %base, <8 x i16> %idxs
   %v = call <8 x half> @llvm.masked.gather.v8f16.v8p0(<8 x ptr> %ptrs, i32 2, <8 x i1> %m, <8 x half> %passthru)
   ret <8 x half> %v
@@ -16109,13 +16109,13 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vand.vx v8, v8, a2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 1
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_11
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_10
 ; RV64ZVE32F-NEXT:  # %bb.1: # %else
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_12
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_11
 ; RV64ZVE32F-NEXT:  .LBB133_2: # %else2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_13
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_12
 ; RV64ZVE32F-NEXT:  .LBB133_3: # %else5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB133_5
@@ -16134,32 +16134,20 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vsetivli zero, 4, e16, m1, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 16
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_14
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_13
 ; RV64ZVE32F-NEXT:  # %bb.6: # %else11
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_15
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_14
 ; RV64ZVE32F-NEXT:  .LBB133_7: # %else14
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
-; RV64ZVE32F-NEXT:    bnez a2, .LBB133_16
+; RV64ZVE32F-NEXT:    bnez a2, .LBB133_15
 ; RV64ZVE32F-NEXT:  .LBB133_8: # %else17
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    beqz a1, .LBB133_10
-; RV64ZVE32F-NEXT:  .LBB133_9: # %cond.load19
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
-; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
-; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
-; RV64ZVE32F-NEXT:    slli a1, a1, 49
-; RV64ZVE32F-NEXT:    srli a1, a1, 48
-; RV64ZVE32F-NEXT:    add a0, a0, a1
-; RV64ZVE32F-NEXT:    lh a0, 0(a0)
-; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
-; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
-; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
-; RV64ZVE32F-NEXT:  .LBB133_10: # %else20
-; RV64ZVE32F-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
+; RV64ZVE32F-NEXT:    bnez a1, .LBB133_16
+; RV64ZVE32F-NEXT:  .LBB133_9: # %else20
 ; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
 ; RV64ZVE32F-NEXT:    ret
-; RV64ZVE32F-NEXT:  .LBB133_11: # %cond.load
+; RV64ZVE32F-NEXT:  .LBB133_10: # %cond.load
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 49
 ; RV64ZVE32F-NEXT:    srli a2, a2, 48
@@ -16169,7 +16157,7 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vmv.s.x v9, a2
 ; RV64ZVE32F-NEXT:    andi a2, a1, 2
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB133_2
-; RV64ZVE32F-NEXT:  .LBB133_12: # %cond.load1
+; RV64ZVE32F-NEXT:  .LBB133_11: # %cond.load1
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -16182,7 +16170,7 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 1
 ; RV64ZVE32F-NEXT:    andi a2, a1, 4
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB133_3
-; RV64ZVE32F-NEXT:  .LBB133_13: # %cond.load4
+; RV64ZVE32F-NEXT:  .LBB133_12: # %cond.load4
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -16196,7 +16184,7 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    andi a2, a1, 8
 ; RV64ZVE32F-NEXT:    bnez a2, .LBB133_4
 ; RV64ZVE32F-NEXT:    j .LBB133_5
-; RV64ZVE32F-NEXT:  .LBB133_14: # %cond.load10
+; RV64ZVE32F-NEXT:  .LBB133_13: # %cond.load10
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v8
 ; RV64ZVE32F-NEXT:    slli a2, a2, 49
 ; RV64ZVE32F-NEXT:    srli a2, a2, 48
@@ -16207,7 +16195,7 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 4
 ; RV64ZVE32F-NEXT:    andi a2, a1, 32
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB133_7
-; RV64ZVE32F-NEXT:  .LBB133_15: # %cond.load13
+; RV64ZVE32F-NEXT:  .LBB133_14: # %cond.load13
 ; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 1
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -16220,7 +16208,7 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 5
 ; RV64ZVE32F-NEXT:    andi a2, a1, 64
 ; RV64ZVE32F-NEXT:    beqz a2, .LBB133_8
-; RV64ZVE32F-NEXT:  .LBB133_16: # %cond.load16
+; RV64ZVE32F-NEXT:  .LBB133_15: # %cond.load16
 ; RV64ZVE32F-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma
 ; RV64ZVE32F-NEXT:    vslidedown.vi v10, v8, 2
 ; RV64ZVE32F-NEXT:    vmv.x.s a2, v10
@@ -16232,8 +16220,20 @@ define <8 x i16> @mgather_baseidx_and_v8i16_v8i16(ptr %base, <8 x i16> %idxs, <8
 ; RV64ZVE32F-NEXT:    vsetivli zero, 7, e16, m1, tu, ma
 ; RV64ZVE32F-NEXT:    vslideup.vi v9, v10, 6
 ; RV64ZVE32F-NEXT:    andi a1, a1, -128
-; RV64ZVE32F-NEXT:    bnez a1, .LBB133_9
-; RV64ZVE32F-NEXT:    j .LBB133_10
+; RV64ZVE32F-NEXT:    beqz a1, .LBB133_9
+; RV64ZVE32F-NEXT:  .LBB133_16: # %cond.load19
+; RV64ZVE32F-NEXT:    vsetivli zero, 1, e16, mf2, ta, ma
+; RV64ZVE32F-NEXT:    vslidedown.vi v8, v8, 3
+; RV64ZVE32F-NEXT:    vmv.x.s a1, v8
+; RV64ZVE32F-NEXT:    slli a1, a1, 49
+; RV64ZVE32F-NEXT:    srli a1, a1, 48
+; RV64ZVE32F-NEXT:    add a0, a0, a1
+; RV64ZVE32F-NEXT:    lh a0, 0(a0)
+; RV64ZVE32F-NEXT:    vmv.s.x v8, a0
+; RV64ZVE32F-NEXT:    vsetivli zero, 8, e16, m1, ta, ma
+; RV64ZVE32F-NEXT:    vslideup.vi v9, v8, 7
+; RV64ZVE32F-NEXT:    vmv1r.v v8, v9
+; RV64ZVE32F-NEXT:    ret
   %eidxs = and <8 x i16> %idxs, splat (i16 32767)
   %ptrs = getelementptr inbounds i16, ptr %base, <8 x i16> %eidxs
   %v = call <8 x i16> @llvm.masked.gather.v8i16.v8p0(<8 x ptr> %ptrs, i32 2, <8 x i1> %m, <8 x i16> %passthru)
diff --git a/llvm/test/CodeGen/RISCV/rvv/vp-vector-interleaved-access.ll b/llvm/test/CodeGen/RISCV/rvv/vp-vector-interleaved-access.ll
index fd46b99bd98e33..2f12d70abbc394 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vp-vector-interleaved-access.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vp-vector-interleaved-access.ll
@@ -62,12 +62,11 @@ define {<vscale x 2 x i32>, <vscale x 2 x i32>} @load_factor3_no_extract(ptr %pt
 ; CHECK-NEXT:  # %bb.1: # %bb0
 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
 ; CHECK-NEXT:    vlseg3e32.v v7, (a0)
-; CHECK-NEXT:    j .LBB3_3
+; CHECK-NEXT:    vmv1r.v v8, v7
+; CHECK-NEXT:    ret
 ; CHECK-NEXT:  .LBB3_2: # %bb1
 ; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
 ; CHECK-NEXT:    vlseg3e32.v v7, (a0)
-; CHECK-NEXT:  .LBB3_3: # %merge
-; CHECK-NEXT:    vsetivli zero, 1, e8, m1, ta, ma
 ; CHECK-NEXT:    vmv1r.v v8, v7
 ; CHECK-NEXT:    ret
   %p = icmp ne i32 %evl, 12
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.ll
new file mode 100644
index 00000000000000..fabe4b102ada49
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.ll
@@ -0,0 +1,390 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+v,-c -verify-machineinstrs -riscv-prefer-whole-register-move=false < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 -mattr=+v,-c -verify-machineinstrs -riscv-prefer-whole-register-move=true < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 -mattr=+v,-c -verify-machineinstrs -riscv-insert-vsetvli-whole-vector-register-move-valid-vtype=false < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 -mattr=+v,+c -verify-machineinstrs < %s | FileCheck %s --check-prefix=C
+; RUN: llc -O0 -mtriple=riscv64 -mattr=+v,-c -verify-machineinstrs < %s | FileCheck %s --check-prefix=O0
+
+target triple = "riscv64"
+declare <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64>,<vscale x 1 x i64>,<vscale x 1 x i64>,i64)
+declare <vscale x 1 x i64> @llvm.riscv.vsub.nxv1i64.nxv1i64(<vscale x 1 x i64>,<vscale x 1 x i64>,<vscale x 1 x i64>,i64)
+declare void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64>,ptr,i64)
+declare i64 @llvm.riscv.vmv.x.s.nxv1i64(<vscale x 1 x i64>)
+define i64 @join_extract(<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i1 %cond,i64 %vl,ptr %p) {
+; CHECK-LABEL: join_extract:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    andi a0, a0, 1
+; CHECK-NEXT:    beqz a0, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %then
+; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; CHECK-NEXT:    vadd.vv v8, v8, v9
+; CHECK-NEXT:    vse64.v v8, (a2)
+; CHECK-NEXT:    vmv.x.s a0, v8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2: # %else
+; CHECK-NEXT:    vsetivli zero, 7, e64, m1, ta, ma
+; CHECK-NEXT:    vsub.vv v8, v8, v9
+; CHECK-NEXT:    vse64.v v8, (a2)
+; CHECK-NEXT:    vmv.x.s a0, v8
+; CHECK-NEXT:    ret
+;
+; C-LABEL: join_extract:
+; C:       # %bb.0: # %entry
+; C-NEXT:    andi a0, a0, 1
+; C-NEXT:    beqz a0, .LBB0_2
+; C-NEXT:  # %bb.1: # %then
+; C-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; C-NEXT:    vadd.vv v8, v8, v9
+; C-NEXT:    vse64.v v8, (a2)
+; C-NEXT:    vmv.x.s a0, v8
+; C-NEXT:    ret
+; C-NEXT:  .LBB0_2: # %else
+; C-NEXT:    vsetivli zero, 7, e64, m1, ta, ma
+; C-NEXT:    vsub.vv v8, v8, v9
+; C-NEXT:    vse64.v v8, (a2)
+; C-NEXT:    vmv.x.s a0, v8
+; C-NEXT:    ret
+;
+; O0-LABEL: join_extract:
+; O0:       # %bb.0: # %entry
+; O0-NEXT:    addi sp, sp, -32
+; O0-NEXT:    .cfi_def_cfa_offset 32
+; O0-NEXT:    csrr a3, vlenb
+; O0-NEXT:    slli a4, a3, 1
+; O0-NEXT:    add a3, a4, a3
+; O0-NEXT:    sub sp, sp, a3
+; O0-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x03, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 3 * vlenb
+; O0-NEXT:    sd a2, 16(sp) # 8-byte Folded Spill
+; O0-NEXT:    sd a1, 24(sp) # 8-byte Folded Spill
+; O0-NEXT:    mv a1, a0
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v9, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    slli a0, a0, 1
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    andi a0, a1, 1
+; O0-NEXT:    beqz a0, .LBB0_2
+; O0-NEXT:    j .LBB0_1
+; O0-NEXT:  .LBB0_1: # %then
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    ld a1, 24(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    slli a2, a2, 1
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v9, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v10, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetvli zero, a1, e64, m1, tu, ma
+; O0-NEXT:    vadd.vv v8, v9, v10
+; O0-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; O0-NEXT:    vse64.v v8, (a0)
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    j .LBB0_3
+; O0-NEXT:  .LBB0_2: # %else
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    slli a1, a1, 1
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v9, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v10, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetivli zero, 7, e64, m1, tu, ma
+; O0-NEXT:    vsub.vv v8, v9, v10
+; O0-NEXT:    vse64.v v8, (a0)
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    j .LBB0_3
+; O0-NEXT:  .LBB0_3: # %join
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vl1r.v v8, (a0) # vscale x 8-byte Folded Reload
+; O0-NEXT:    vsetivli zero, 1, e64, m1, ta, ma
+; O0-NEXT:    vmv.x.s a0, v8
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    slli a2, a1, 1
+; O0-NEXT:    add a1, a2, a1
+; O0-NEXT:    add sp, sp, a1
+; O0-NEXT:    .cfi_def_cfa sp, 32
+; O0-NEXT:    addi sp, sp, 32
+; O0-NEXT:    .cfi_def_cfa_offset 0
+; O0-NEXT:    ret
+entry:
+ br i1 %cond,label %then,label %else
+then:
+ %a=call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison,<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i64 %vl)
+ call void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64> %a,ptr %p,i64 %vl)
+ br label %join
+else:
+ %b=call <vscale x 1 x i64> @llvm.riscv.vsub.nxv1i64.nxv1i64(<vscale x 1 x i64> poison,<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i64 7)
+ call void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64> %b,ptr %p,i64 7)
+ br label %join
+join:
+ %v=phi <vscale x 1 x i64> [%a,%then],[%b,%else]
+ %out=call i64 @llvm.riscv.vmv.x.s.nxv1i64(<vscale x 1 x i64> %v)
+ ret i64 %out
+}
+
+
+declare <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32>,<vscale x 2 x i32>,<vscale x 2 x i32>,i64)
+declare void @llvm.riscv.vse.nxv2i32(<vscale x 2 x i32>,ptr,i64)
+define <vscale x 1 x i64> @join_copy(<vscale x 1 x i64> %x, <vscale x 1 x i64> %y, <vscale x 1 x i64> %z, i1 %cond, i64 %vl, ptr %p) {
+; CHECK-LABEL: join_copy:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    andi a0, a0, 1
+; CHECK-NEXT:    beqz a0, .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %then
+; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; CHECK-NEXT:    vadd.vv v8, v8, v9
+; CHECK-NEXT:    vse64.v v8, (a2)
+; CHECK-NEXT:    vmv1r.v v8, v10
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2: # %else
+; CHECK-NEXT:    vsetivli zero, 7, e32, m1, ta, ma
+; CHECK-NEXT:    vadd.vv v8, v8, v9
+; CHECK-NEXT:    vse32.v v8, (a2)
+; CHECK-NEXT:    vmv1r.v v8, v10
+; CHECK-NEXT:    ret
+;
+; C-LABEL: join_copy:
+; C:       # %bb.0: # %entry
+; C-NEXT:    andi a0, a0, 1
+; C-NEXT:    beqz a0, .LBB1_2
+; C-NEXT:  # %bb.1: # %then
+; C-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; C-NEXT:    vadd.vv v8, v8, v9
+; C-NEXT:    vse64.v v8, (a2)
+; C-NEXT:    vmv1r.v v8, v10
+; C-NEXT:    ret
+; C-NEXT:  .LBB1_2: # %else
+; C-NEXT:    vsetivli zero, 7, e32, m1, ta, ma
+; C-NEXT:    vadd.vv v8, v8, v9
+; C-NEXT:    vse32.v v8, (a2)
+; C-NEXT:    vmv1r.v v8, v10
+; C-NEXT:    ret
+;
+; O0-LABEL: join_copy:
+; O0:       # %bb.0: # %entry
+; O0-NEXT:    addi sp, sp, -32
+; O0-NEXT:    .cfi_def_cfa_offset 32
+; O0-NEXT:    csrr a3, vlenb
+; O0-NEXT:    slli a4, a3, 1
+; O0-NEXT:    add a3, a4, a3
+; O0-NEXT:    sub sp, sp, a3
+; O0-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x03, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 3 * vlenb
+; O0-NEXT:    sd a2, 16(sp) # 8-byte Folded Spill
+; O0-NEXT:    sd a1, 24(sp) # 8-byte Folded Spill
+; O0-NEXT:    mv a1, a0
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vs1r.v v10, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v9, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    slli a0, a0, 1
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    andi a0, a1, 1
+; O0-NEXT:    beqz a0, .LBB1_2
+; O0-NEXT:    j .LBB1_1
+; O0-NEXT:  .LBB1_1: # %then
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    ld a1, 24(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    slli a2, a2, 1
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v9, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v10, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetvli zero, a1, e64, m1, tu, ma
+; O0-NEXT:    vadd.vv v8, v9, v10
+; O0-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; O0-NEXT:    vse64.v v8, (a0)
+; O0-NEXT:    j .LBB1_3
+; O0-NEXT:  .LBB1_2: # %else
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    slli a1, a1, 1
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v9, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v10, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetivli zero, 7, e32, m1, tu, ma
+; O0-NEXT:    vadd.vv v8, v9, v10
+; O0-NEXT:    vse32.v v8, (a0)
+; O0-NEXT:    j .LBB1_3
+; O0-NEXT:  .LBB1_3: # %join
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vl1r.v v8, (a0) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    slli a1, a0, 1
+; O0-NEXT:    add a0, a1, a0
+; O0-NEXT:    add sp, sp, a0
+; O0-NEXT:    .cfi_def_cfa sp, 32
+; O0-NEXT:    addi sp, sp, 32
+; O0-NEXT:    .cfi_def_cfa_offset 0
+; O0-NEXT:    ret
+entry:
+ br i1 %cond,label %then,label %else
+then:
+ %a=call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison,<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i64 %vl)
+ call void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64> %a,ptr %p,i64 %vl)
+ br label %join
+else:
+ %xx=bitcast <vscale x 1 x i64> %x to <vscale x 2 x i32>
+ %yy=bitcast <vscale x 1 x i64> %y to <vscale x 2 x i32>
+ %b=call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> poison,<vscale x 2 x i32> %xx,<vscale x 2 x i32> %yy,i64 7)
+ call void @llvm.riscv.vse.nxv2i32(<vscale x 2 x i32> %b,ptr %p,i64 7)
+ br label %join
+join:
+ ret <vscale x 1 x i64> %z
+}
+
+
+; A zero-AVL predecessor still supplies a legal exact type.
+define i64 @join_extract_zero(<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i1 %cond,i64 %vl,ptr %p) {
+; CHECK-LABEL: join_extract_zero:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    andi a0, a0, 1
+; CHECK-NEXT:    beqz a0, .LBB2_2
+; CHECK-NEXT:  # %bb.1: # %then
+; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; CHECK-NEXT:    vadd.vv v8, v8, v9
+; CHECK-NEXT:    vse64.v v8, (a2)
+; CHECK-NEXT:    vmv.x.s a0, v8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB2_2: # %else
+; CHECK-NEXT:    vsetivli zero, 0, e64, m1, ta, ma
+; CHECK-NEXT:    vsub.vv v8, v8, v9
+; CHECK-NEXT:    vse64.v v8, (a2)
+; CHECK-NEXT:    vmv.x.s a0, v8
+; CHECK-NEXT:    ret
+;
+; C-LABEL: join_extract_zero:
+; C:       # %bb.0: # %entry
+; C-NEXT:    andi a0, a0, 1
+; C-NEXT:    beqz a0, .LBB2_2
+; C-NEXT:  # %bb.1: # %then
+; C-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; C-NEXT:    vadd.vv v8, v8, v9
+; C-NEXT:    vse64.v v8, (a2)
+; C-NEXT:    vmv.x.s a0, v8
+; C-NEXT:    ret
+; C-NEXT:  .LBB2_2: # %else
+; C-NEXT:    vsetivli zero, 0, e64, m1, ta, ma
+; C-NEXT:    vsub.vv v8, v8, v9
+; C-NEXT:    vse64.v v8, (a2)
+; C-NEXT:    vmv.x.s a0, v8
+; C-NEXT:    ret
+;
+; O0-LABEL: join_extract_zero:
+; O0:       # %bb.0: # %entry
+; O0-NEXT:    addi sp, sp, -32
+; O0-NEXT:    .cfi_def_cfa_offset 32
+; O0-NEXT:    csrr a3, vlenb
+; O0-NEXT:    slli a4, a3, 1
+; O0-NEXT:    add a3, a4, a3
+; O0-NEXT:    sub sp, sp, a3
+; O0-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x03, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 3 * vlenb
+; O0-NEXT:    sd a2, 16(sp) # 8-byte Folded Spill
+; O0-NEXT:    sd a1, 24(sp) # 8-byte Folded Spill
+; O0-NEXT:    mv a1, a0
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v9, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    csrr a0, vlenb
+; O0-NEXT:    slli a0, a0, 1
+; O0-NEXT:    add a0, sp, a0
+; O0-NEXT:    addi a0, a0, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    andi a0, a1, 1
+; O0-NEXT:    beqz a0, .LBB2_2
+; O0-NEXT:    j .LBB2_1
+; O0-NEXT:  .LBB2_1: # %then
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    ld a1, 24(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    slli a2, a2, 1
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v9, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a2, vlenb
+; O0-NEXT:    add a2, sp, a2
+; O0-NEXT:    addi a2, a2, 32
+; O0-NEXT:    vl1r.v v10, (a2) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetvli zero, a1, e64, m1, tu, ma
+; O0-NEXT:    vadd.vv v8, v9, v10
+; O0-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
+; O0-NEXT:    vse64.v v8, (a0)
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    j .LBB2_3
+; O0-NEXT:  .LBB2_2: # %else
+; O0-NEXT:    ld a0, 16(sp) # 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    slli a1, a1, 1
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v9, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    add a1, sp, a1
+; O0-NEXT:    addi a1, a1, 32
+; O0-NEXT:    vl1r.v v10, (a1) # vscale x 8-byte Folded Reload
+; O0-NEXT:    # implicit-def: $v8
+; O0-NEXT:    vsetivli zero, 0, e64, m1, tu, ma
+; O0-NEXT:    vsub.vv v8, v9, v10
+; O0-NEXT:    vse64.v v8, (a0)
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill
+; O0-NEXT:    j .LBB2_3
+; O0-NEXT:  .LBB2_3: # %join
+; O0-NEXT:    addi a0, sp, 32
+; O0-NEXT:    vl1r.v v8, (a0) # vscale x 8-byte Folded Reload
+; O0-NEXT:    vsetivli zero, 1, e64, m1, ta, ma
+; O0-NEXT:    vmv.x.s a0, v8
+; O0-NEXT:    csrr a1, vlenb
+; O0-NEXT:    slli a2, a1, 1
+; O0-NEXT:    add a1, a2, a1
+; O0-NEXT:    add sp, sp, a1
+; O0-NEXT:    .cfi_def_cfa sp, 32
+; O0-NEXT:    addi sp, sp, 32
+; O0-NEXT:    .cfi_def_cfa_offset 0
+; O0-NEXT:    ret
+entry:
+ br i1 %cond,label %then,label %else
+then:
+ %a=call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison,<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i64 %vl)
+ call void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64> %a,ptr %p,i64 %vl)
+ br label %join
+else:
+ %b=call <vscale x 1 x i64> @llvm.riscv.vsub.nxv1i64.nxv1i64(<vscale x 1 x i64> poison,<vscale x 1 x i64> %x,<vscale x 1 x i64> %y,i64 0)
+ call void @llvm.riscv.vse.nxv1i64(<vscale x 1 x i64> %b,ptr %p,i64 0)
+ br label %join
+join:
+ %v=phi <vscale x 1 x i64> [%a,%then],[%b,%else]
+ %out=call i64 @llvm.riscv.vmv.x.s.nxv1i64(<vscale x 1 x i64> %v)
+ ret i64 %out
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.mir
new file mode 100644
index 00000000000000..6fed41f6d2a56b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-independent-type-facts.mir
@@ -0,0 +1,1243 @@
+# RUN: llc -mtriple=riscv64 -run-pass=riscv-insert-vsetvli -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,NOLIS
+# RUN: llc -mtriple=riscv32 -run-pass=riscv-insert-vsetvli -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,NOLIS
+# RUN: llc -mtriple=riscv64 -run-pass=slotindexes,riscv-insert-vsetvli -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,NOLIS
+# RUN: llc -mtriple=riscv64 -run-pass=liveintervals,riscv-insert-vsetvli -precompute-phys-liveness -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,LIS
+
+# Facts describe the final emitted stream independently of AVL/VL. Each
+# negative checks that a join setup survives; positive checks preserve the
+# consumer while excluding a setup in its block. The optional-chain tests
+# require fixed membership and independently justified batch deletion.
+
+--- |
+  target triple = "riscv64"
+  define i64 @same_type_different_avl() #0 { ret i64 0 }
+  define i64 @same_type_same_avl() #0 { ret i64 0 }
+  define i64 @unknown_predecessor() #0 { ret i64 0 }
+  define i64 @illegal_explicit() #0 { ret i64 0 }
+  define i64 @three_predecessors() #0 { ret i64 0 }
+  define i64 @three_one_incompatible() #0 { ret i64 0 }
+  define i64 @nested_diamond() #0 { ret i64 0 }
+  define i64 @safe_independent_backedge() #0 { ret i64 0 }
+  define i64 @unsafe_changed_backedge() #0 { ret i64 0 }
+  define i64 @first_iteration_unknown() #0 { ret i64 0 }
+  define i64 @later_full_vl() #0 { ret i64 0 }
+  define i64 @raw_vl_observer() #0 { ret i64 0 }
+  define i64 @different_policy() #0 { ret i64 0 }
+  define i64 @different_lmul() #0 { ret i64 0 }
+  define i64 @floating_extract() #0 { ret i64 0 }
+  define i64 @raw_vstart() #0 { ret i64 0 }
+  define i64 @system_observer() #0 { ret i64 0 }
+  define i64 @unexpected_extract_operand() #0 { ret i64 0 }
+  define i64 @return_state_operand() #0 { ret i64 0 }
+  define i64 @later_scalar_memory() #0 { ret i64 0 }
+  define i64 @unreachable_scc() #0 { ret i64 0 }
+  define i64 @optional_chain_batch() #0 { ret i64 0 }
+  define i64 @optional_shields_observer() #0 { ret i64 0 }
+  define i64 @different_type_whole_copy() #0 { ret i64 0 }
+  define i64 @copy_local_source_producer() #0 { ret i64 0 }
+  define i64 @optional_only_backedge() #0 { ret i64 0 }
+  define i64 @irreducible_independent_seeds() #0 { ret i64 0 }
+  define i64 @zve32x_e32() #1 { ret i64 0 }
+  define i64 @zve32x_e64_rejected() #1 { ret i64 0 }
+  define i64 @original_call() #0 { ret i64 0 }
+  define i64 @original_inline_asm() #0 { ret i64 0 }
+  define i64 @original_fault_first() #0 { ret i64 0 }
+  define i64 @x0x0_continuation() #0 { ret i64 0 }
+  define i64 @unexpected_return_operand() #0 { ret i64 0 }
+  define i64 @incompatible_sew_successors() #0 { ret i64 0 }
+  define i64 @legal_only_and_sew_successors() #0 { ret i64 0 }
+  attributes #0 = { "target-features"="+v" }
+  attributes #1 = { "target-features"="-v,-zve64d,-zve64f,-zve64x,+zve32x" }
+...
+---
+name: same_type_different_avl
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: same_type_different_avl
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 0, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: same_type_same_avl
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: same_type_same_avl
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: unknown_predecessor
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: unknown_predecessor
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: illegal_explicit
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: illegal_explicit
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   dead $x0 = PseudoVSETIVLI 1, 221, implicit-def $vl, implicit-def $vtype
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: three_predecessors
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: three_predecessors
+ ; CHECK: bb.5:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.5
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.5
+ bb.2:
+   successors: %bb.3, %bb.4
+   BEQ %c, $x0, %bb.4
+   PseudoBR %bb.3
+ bb.3:
+   successors: %bb.5
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.5
+ bb.4:
+   successors: %bb.5
+   %d:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 9, 6, 0
+   PseudoBR %bb.5
+ bb.5:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: three_one_incompatible
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: three_one_incompatible
+ ; CHECK: bb.5:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.5
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.5
+ bb.2:
+   successors: %bb.3, %bb.4
+   BEQ %c, $x0, %bb.4
+   PseudoBR %bb.3
+ bb.3:
+   successors: %bb.5
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.5
+ bb.4:
+   successors: %bb.5
+   %d:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 9, 5, 0
+   PseudoBR %bb.5
+ bb.5:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: nested_diamond
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: nested_diamond
+ ; CHECK: bb.5:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: liveins: $vtype
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoBR %bb.6
+ ; CHECK: bb.6:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: liveins: $vtype
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3, %bb.4
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   BEQ %c, $x0, %bb.4
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.5
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.5
+ bb.3:
+   successors: %bb.5
+   PseudoBR %bb.5
+ bb.4:
+   successors: %bb.5
+   PseudoBR %bb.5
+ bb.5:
+   successors: %bb.6
+   PseudoBR %bb.6
+ bb.6:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: safe_independent_backedge
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: safe_independent_backedge
+ ; CHECK: bb.1:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.2
+   %r:gpr = PseudoVMV_X_S %x, 6
+   PseudoBR %bb.2
+ bb.2:
+   successors: %bb.1, %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   BNE %c, $x0, %bb.1
+   PseudoBR %bb.3
+ bb.3:
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: unsafe_changed_backedge
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: unsafe_changed_backedge
+ ; CHECK: bb.1:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.2
+   %r:gpr = PseudoVMV_X_S %x, 6
+   PseudoBR %bb.2
+ bb.2:
+   successors: %bb.1, %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   BNE %c, $x0, %bb.1
+   PseudoBR %bb.3
+ bb.3:
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: first_iteration_unknown
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: first_iteration_unknown
+ ; CHECK: bb.1:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.2
+   %r:gpr = PseudoVMV_X_S %x, 6
+   PseudoBR %bb.2
+ bb.2:
+   successors: %bb.1, %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   BNE %c, $x0, %bb.1
+   PseudoBR %bb.3
+ bb.3:
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: later_full_vl
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: later_full_vl
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   %later:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 1, 6, 0
+   $v8 = COPY %later
+   $x10 = COPY %r
+   PseudoRET implicit $x10, implicit $v8
+...
+---
+name: raw_vl_observer
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: raw_vl_observer
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   %obs:gpr = CSRRS 3104, $x0, implicit $vl
+   $x10 = COPY %obs
+   PseudoRET implicit $x10
+...
+---
+name: different_policy
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: different_policy
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 %x, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: different_lmul
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: different_lmul
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vrm2 = PseudoVADD_VV_M2 undef $noreg, undef $v8m2, undef $v10m2, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: floating_extract
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: floating_extract
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVFMV_FPR64_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:fpr64 = PseudoVFMV_FPR64_S %x, 6
+   $f10_d = COPY %r
+   PseudoRET implicit $f10_d
+...
+---
+name: raw_vstart
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: raw_vstart
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   dead $x0 = CSRRWI 8, 1
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: system_observer
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: system_observer
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   ECALL
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: unexpected_extract_operand
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: unexpected_extract_operand
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6, implicit $vl
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: return_state_operand
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: return_state_operand
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10, implicit $vtype
+...
+---
+name: later_scalar_memory
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: later_scalar_memory
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   %load:gpr = LD %c, 0
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: unreachable_scc
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: unreachable_scc
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S undef $v8, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+ bb.4:
+   successors: %bb.5
+   %u:vr = PseudoVADD_VV_M1 undef $noreg, undef $v8, undef $v9, 9, 5, 0
+   PseudoBR %bb.5
+ bb.5:
+   successors: %bb.4, %bb.3
+   BNE undef $x10, $x0, %bb.4
+   PseudoBR %bb.3
+...
+---
+name: optional_chain_batch
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: optional_chain_batch
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ ; CHECK: bb.6:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: $v8 = COPY $v10
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9, $v10
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   liveins: $v10
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   liveins: $v10
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   successors: %bb.4, %bb.5
+   liveins: $v10
+   %r:gpr = PseudoVMV_X_S %x, 6
+   BEQ %c, $x0, %bb.4
+   PseudoBR %bb.5
+ bb.4:
+   successors: %bb.6
+   liveins: $v10
+   PseudoBR %bb.6
+ bb.5:
+   successors: %bb.6
+   liveins: $v10
+   %d:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 9, 5, 0
+   PseudoBR %bb.6
+ bb.6:
+   liveins: $v10
+   $v8 = COPY $v10
+   $x10 = COPY %r
+   PseudoRET implicit $x10, implicit $v8
+...
+---
+name: optional_shields_observer
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: optional_shields_observer
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   %s:gpr = PseudoVMV_X_S %x, 5
+   %later:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 1, 5, 0
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: different_type_whole_copy
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: different_type_whole_copy
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: $v8 = COPY $v10
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9, $v10
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   liveins: $v10
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   liveins: $v10
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   PseudoBR %bb.3
+ bb.3:
+   liveins: $v10
+   $v8 = COPY $v10
+   PseudoRET implicit $v8
+...
+---
+name: copy_local_source_producer
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: copy_local_source_producer
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: $v8 = COPY $v10
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9, $v10
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   liveins: $v9, $v10
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   liveins: $v9, $v10
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   PseudoBR %bb.3
+ bb.3:
+   liveins: $v9, $v10
+   $v10 = COPY $v9
+   $v8 = COPY $v10
+   PseudoRET implicit $v8
+...
+---
+name: optional_only_backedge
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: optional_only_backedge
+ ; CHECK: bb.1:
+ ; NOLIS: PseudoVSETVLI
+ ; LIS-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.2
+   %r:gpr = PseudoVMV_X_S %x, 6
+   PseudoBR %bb.2
+ bb.2:
+   successors: %bb.1, %bb.3
+   BNE %c, $x0, %bb.1
+   PseudoBR %bb.3
+ bb.3:
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: irreducible_independent_seeds
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: irreducible_independent_seeds
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.4
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.4
+ bb.3:
+   successors: %bb.4
+   %r:gpr = PseudoVMV_X_S %x, 6
+   PseudoBR %bb.4
+ bb.4:
+   successors: %bb.3, %bb.5
+   %d:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 9, 6, 0
+   BEQ %c, $x0, %bb.3
+   PseudoBR %bb.5
+ bb.5:
+   PseudoRET
+...
+---
+name: zve32x_e32
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: zve32x_e32
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 5, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 5
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: zve32x_e64_rejected
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: zve32x_e64_rejected
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: original_call
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: original_call
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   PseudoCALL $noreg, csr_ilp32_lp64
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: original_inline_asm
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: original_inline_asm
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   INLINEASM &"", sideeffect attdialect
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: original_fault_first
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: original_fault_first
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   %fof:vr, %fofvl:gpr = PseudoVLE64FF_V_M1 undef $noreg, %c, 3, 6, 0
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: x0x0_continuation
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: x0x0_continuation
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   %later:vr = PseudoVMV_V_I_MF2 undef $noreg, 1, 1, 5, 0
+   $x10 = COPY %r
+   PseudoRET implicit $x10
+...
+---
+name: unexpected_return_operand
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: unexpected_return_operand
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 6, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 6, 0
+   PseudoBR %bb.3
+ bb.3:
+   %r:gpr = PseudoVMV_X_S %x, 6
+   $x10 = COPY %r
+   PseudoRET implicit $x10, implicit undef $vxrm
+...
+---
+name: incompatible_sew_successors
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: incompatible_sew_successors
+ ; CHECK: bb.3:
+ ; CHECK: PseudoVSETIVLI 1,
+ ; CHECK: PseudoVMV_X_S
+ ; CHECK: bb.4:
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9, $v10
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   liveins: $v10
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 5, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   liveins: $v10
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   PseudoBR %bb.3
+ bb.3:
+   successors: %bb.4, %bb.5
+   liveins: $v10
+   %r:gpr = PseudoVMV_X_S %x, 5
+   BEQ %c, $x0, %bb.5
+   PseudoBR %bb.4
+ bb.4:
+   liveins: $v10
+   %s:gpr = PseudoVMV_X_S %x, 4
+   $x10 = COPY %s
+   PseudoRET implicit $x10
+ bb.5:
+   %t:gpr = PseudoVMV_X_S %x, 5
+   $x10 = COPY %t
+   PseudoRET implicit $x10
+...
+---
+name: legal_only_and_sew_successors
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: legal_only_and_sew_successors
+ ; CHECK: bb.3:
+ ; CHECK-NOT: PseudoVSET
+ ; CHECK: PseudoVMV_X_S
+ ; CHECK: bb.4:
+ bb.0:
+   successors: %bb.1, %bb.2
+   liveins: $x10, $x11, $v8, $v9, $v10
+   %c:gpr = COPY $x10
+   %vl:gprnox0 = COPY $x11
+   %x:vr = COPY $v8
+   %y:vr = COPY $v9
+   BEQ %c, $x0, %bb.2
+   PseudoBR %bb.1
+ bb.1:
+   successors: %bb.3
+   liveins: $v10
+   %a:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, %vl, 5, 0
+   PseudoBR %bb.3
+ bb.2:
+   successors: %bb.3
+   liveins: $v10
+   %b:vr = PseudoVADD_VV_M1 undef $noreg, %x, %y, 7, 5, 0
+   PseudoBR %bb.3
+ bb.3:
+   successors: %bb.4, %bb.5
+   liveins: $v10
+   %r:gpr = PseudoVMV_X_S %x, 5
+   BEQ %c, $x0, %bb.5
+   PseudoBR %bb.4
+ bb.4:
+   liveins: $v10
+   $v8 = COPY $v10
+   PseudoRET implicit $v8
+ bb.5:
+   %t:gpr = PseudoVMV_X_S %x, 5
+   $x10 = COPY %t
+   PseudoRET implicit $x10
+...



More information about the llvm-commits mailing list