[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