diff --git a/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.h b/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.h new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.h @@ -0,0 +1,52 @@ +//===- RISCVCleanupVSETVLI.h - Shared data structures ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_RISCVCLEANUPVSETVLI_H +#define LLVM_LIB_TARGET_RISCV_RISCVCLEANUPVSETVLI_H + +#include "RISCV.h" +#include "llvm/CodeGen/MachineInstr.h" + +namespace llvm { + +class VSETVLInstr { +public: + VSETVLInstr() : NewVLReg(0), AVL(0), VType(~0U), Opcode(0) {} + + VSETVLInstr(const MachineInstr &MI) + : NewVLReg(MI.getOperand(0).getReg()), VType(MI.getOperand(2).getImm()), + Opcode(MI.getOpcode()) { + if (Opcode == RISCV::PseudoVSETVLI) { + AVL = MI.getOperand(1).getReg(); + } else { + assert(Opcode == RISCV::PseudoVSETIVLI); + AVL = MI.getOperand(1).getImm(); + } + } + + Register getNewVLReg() const { return NewVLReg; } + void setNewVLReg(Register Reg) { NewVLReg = Reg; } + + bool hasSameConfig(const VSETVLInstr &Other) const { + return Opcode == Other.Opcode && AVL == Other.AVL && VType == Other.VType; + } + + bool hasSameNewVLReg(const VSETVLInstr &Other) const { + return NewVLReg == Other.NewVLReg; + } + +private: + Register NewVLReg; + unsigned AVL; + unsigned VType; + unsigned Opcode; +}; + +} // end namespace llvm + +#endif diff --git a/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp --- a/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp @@ -11,14 +11,20 @@ // //===----------------------------------------------------------------------===// +#include "RISCVCleanupVSETVLI.h" #include "RISCV.h" #include "RISCVSubtarget.h" #include "llvm/CodeGen/MachineFunctionPass.h" + using namespace llvm; #define DEBUG_TYPE "riscv-cleanup-vsetvli" #define RISCV_CLEANUP_VSETVLI_NAME "RISCV Cleanup VSETVLI pass" +static cl::opt DisableCleanupVSETVLGlobal( + "riscv-disable-cleanup-vsetvl-global", cl::init(false), cl::Hidden, + cl::desc("Disable removing redundant vsetvl global")); + namespace { class RISCVCleanupVSETVLI : public MachineFunctionPass { @@ -140,6 +146,198 @@ return Changed; } +static bool findLastVSETVLChange(const MachineBasicBlock &MBB, + VSETVLInstr &VI) { + // Instantiate 'Unmatched' value (as per the default constructor). + // Unmatched value means that we may observe the effects of different VSETVLI + // instructions along different paths that lead to the same program point. + const VSETVLInstr Unmatched; + for (auto MII = MBB.rbegin(), MIE = MBB.rend(); MII != MIE; ++MII) { + if (MII->getOpcode() == RISCV::PseudoVSETVLI || + MII->getOpcode() == RISCV::PseudoVSETIVLI) { + // We found a VSET[I]VLI, store it as the output for this block. + VI = *MII; + return true; + } else if (MII->modifiesRegister(RISCV::VL) || MII->isCall()) { + // We found some other instruction that modifies VL, mark output as + // unmatched. + VI = Unmatched; + return true; + } + } + return false; +} + +static Optional collectVIFromPreds( + const MachineBasicBlock &MBB, + SmallVectorImpl> &BBVSETVLInstrOutMap) { + const VSETVLInstr Unmatched; + Optional VI; + if (MBB.pred_empty()) { + // If no predecessors (entry MBB), In[MBB] := Unmatched. + // We cannot claim anything about the incoming VSETVLI instruction, so + // the only sensible value here is Unmatched. This is the most + // conservative value. + return Unmatched; + } + for (const MachineBasicBlock *Pred : MBB.predecessors()) { + assert(Pred != nullptr && "Unexpected NULL basic block"); + Optional PVI = BBVSETVLInstrOutMap[Pred->getNumber()]; + + // VI ∧ Undef = VI. + if (!PVI.hasValue()) + continue; + + if (!VI.hasValue()) { + // Undef ∧ VI = VI + VI = PVI.getValue(); + continue; + } + + if (!VI->hasSameConfig(*PVI)) { + // VI ∧ different VI = Unmatched. + + // Unmatched ∧ * = Unmatched. + return Unmatched; + } + + if (!VI->hasSameNewVLReg(*PVI)) { + // If the config matches, but the NewVL doesn't, clear the NewVL. We + // need this for optimizing across PHIs. + VI->setNewVLReg(RISCV::NoRegister); + // Don't break the loop. We might still have a config mismatch that + // needs to reset the AVL/Type. + } + // else VI ∧ equal VI = VI. + } + return VI; +} + +static void initBBVSETVLInstrInMap( + SmallVectorImpl> &BBVSETVLInstrInMap, + const MachineFunction &MF) { + + BitVector ModifiesVL(MF.getNumBlockIDs()); + + SmallVector, 32> BBVSETVLInstrOutMap( + MF.getNumBlockIDs()); + + // Compute the last VSETVLI instruction found in each basic blocks (if any). + for (const MachineBasicBlock &MBB : MF) { + VSETVLInstr VI; + if (findLastVSETVLChange(MBB, VI)) { + ModifiesVL[MBB.getNumber()] = true; + BBVSETVLInstrOutMap[MBB.getNumber()] = VI; + } + } + + SmallVector Worklist; + SmallBitVector InWorkList(MF.getNumBlockIDs(), true); + + for (const MachineBasicBlock &MBB : make_range(MF.rbegin(), MF.rend())) + Worklist.push_back(&MBB); + + while (!Worklist.empty()) { + + const MachineBasicBlock &MBB = *Worklist.pop_back_val(); + InWorkList[MBB.getNumber()] = false; + + Optional VI = collectVIFromPreds(MBB, BBVSETVLInstrOutMap); + + // In[MBB] == Undef, no updates. + if (!VI.hasValue()) + continue; + + // Update the solution map. + BBVSETVLInstrInMap[MBB.getNumber()] = VI.getValue(); + + // Apply transfer function over MBB. + + // If there is an explicit VSETVLI instruction in MBB, Out[MBB] is fixed. + if (ModifiesVL[MBB.getNumber()]) + continue; + + // Out[MBB] hasn't changed. + if (BBVSETVLInstrOutMap[MBB.getNumber()].hasValue() && + BBVSETVLInstrOutMap[MBB.getNumber()]->hasSameConfig(*VI) && + BBVSETVLInstrOutMap[MBB.getNumber()]->hasSameNewVLReg(*VI)) + continue; + + // Update Out[MBB] and account for changes. + BBVSETVLInstrOutMap[MBB.getNumber()] = VI.getValue(); + for (auto BBI = MBB.succ_begin(), BBE = MBB.succ_end(); BBI != BBE; ++BBI) { + if (!InWorkList[(*BBI)->getNumber()]) { + Worklist.push_back(*BBI); + InWorkList[(*BBI)->getNumber()] = true; + } + } + } +} + +static bool removeRedundantVSETVLIGlobal(MachineFunction &MF) { + bool Changed = false; + + const MachineRegisterInfo &MRI = MF.getRegInfo(); + + SmallVector, 32> BBVSETVLInstrInMap( + MF.getNumBlockIDs()); + + initBBVSETVLInstrInMap(BBVSETVLInstrInMap, MF); + + for (MachineBasicBlock &MBB : MF) { + Optional InVI = BBVSETVLInstrInMap[MBB.getNumber()]; + // Undef shouldn't appear in the solution. + assert(InVI.hasValue() && "Unexpected 'Undef' after data flow convergence"); + + MachineInstr *FirstVSETVLInstr = nullptr; + for (MachineInstr &MI : MBB) { + if (MI.getOpcode() == RISCV::PseudoVSETVLI || + MI.getOpcode() == RISCV::PseudoVSETIVLI) { + FirstVSETVLInstr = &MI; + break; + } else if (MI.modifiesRegister(RISCV::VL) || MI.isCall()) { + break; + } + } + + if (!FirstVSETVLInstr) + continue; + + LLVM_DEBUG(dbgs() << "Considering removal of \n"; + FirstVSETVLInstr->dump();); + + VSETVLInstr FirstVI(*FirstVSETVLInstr); + Register NewVLReg = FirstVI.getNewVLReg(); + assert((NewVLReg.isVirtual() || NewVLReg == RISCV::X0) && + "NewVL must be a virtual register or X0!"); + + // Don't remove VSETVLI whose NewVL is being used. + // FIXME: Replace uses with predecessor's NewVL, using a phi if necessary. + if (NewVLReg.isVirtual() && !MRI.use_empty(NewVLReg)) { + LLVM_DEBUG(dbgs() << "Not removing because its value is still used.\n"; + dbgs() << "Printing uses of defined register " + << printReg(NewVLReg) << "\n"; + for (auto UIt = MRI.use_begin(NewVLReg), UEnd = MRI.use_end(); + UIt != UEnd; UIt++) { + MachineOperand &MO = *UIt; + MachineInstr *MI = MO.getParent(); + MI->dump(); + }); + continue; + } + + if (InVI->hasSameConfig(FirstVI)) { + LLVM_DEBUG(dbgs() << "Remove redundant VSETVLI instruction leading BB '" + << MBB.getNumber() << "." << MBB.getName() << "':\n"; + FirstVSETVLInstr->dump(); dbgs() << "\n"); + FirstVSETVLInstr->eraseFromParent(); + Changed = true; + continue; + } + } + return Changed; +} + bool RISCVCleanupVSETVLI::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(MF.getFunction())) return false; @@ -154,6 +352,9 @@ for (MachineBasicBlock &MBB : MF) Changed |= runOnMachineBasicBlock(MBB); + if (!DisableCleanupVSETVLGlobal) + Changed |= removeRedundantVSETVLIGlobal(MF); + return Changed; } diff --git a/llvm/test/CodeGen/RISCV/rvv/cleanup-vsetvli-global.mir b/llvm/test/CodeGen/RISCV/rvv/cleanup-vsetvli-global.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/cleanup-vsetvli-global.mir @@ -0,0 +1,136 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc %s -mtriple=riscv64 -run-pass=riscv-cleanup-vsetvli -o - | FileCheck %s + +--- | + ; ModuleID = '../llvm/test/CodeGen/RISCV/rvv/add-vsetvli-vlmax.ll' + source_filename = "../llvm/test/CodeGen/RISCV/rvv/add-vsetvli-vlmax.ll" + target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128" + target triple = "riscv64" + + define void @cleanup_vsetvli_global_1() #0 { + ret void + } + + define void @cleanup_vsetvli_global_2() #0 { + ret void + } + + define void @cleanup_vsetvli_global_3() #0 { + ret void + } + + define void @cleanup_vsetvli_global_4() #0 { + ret void + } + + attributes #0 = { "target-features"="+experimental-v" } + +... +--- +# Check that one VSETVLI is removed if it matches all coming VSETVLIs from predecessors. +name: cleanup_vsetvli_global_1 +alignment: 4 +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: cleanup_vsetvli_global_1 + ; CHECK: bb.0 (%ir-block.0): + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: dead %0:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoBR %bb.2 + ; CHECK: bb.1: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: dead %1:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoBR %bb.3 + ; CHECK: bb.2: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: bb.3: + ; CHECK: PseudoRET + bb.0 (%ir-block.0): + dead %0:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoBR %bb.2 + bb.1: + dead %10:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoBR %bb.3 + bb.2: + bb.3: + dead %20:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoRET +... +--- +# Check that VSETVLI is not removed if the config doesn't match one of its precessors's. +name: cleanup_vsetvli_global_2 +alignment: 4 +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: cleanup_vsetvli_global_2 + ; CHECK: bb.0 (%ir-block.0): + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: dead %0:gpr = PseudoVSETIVLI 2, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoBR %bb.2 + ; CHECK: bb.1: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: dead %1:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoBR %bb.3 + ; CHECK: bb.2: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: PseudoBR %bb.3 + ; CHECK: bb.3: + ; CHECK: dead %2:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoRET + bb.0 (%ir-block.0): + dead %0:gpr = PseudoVSETIVLI 2, 88, implicit-def $vl, implicit-def $vtype + PseudoBR %bb.2 + bb.1: + dead %10:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoBR %bb.3 + bb.2: + PseudoBR %bb.3 + bb.3: + dead %20:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoRET +... +--- +# Check that VSETVLI is not removed if one of predecessors doesn't define VSETVLI. +name: cleanup_vsetvli_global_3 +alignment: 4 +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: cleanup_vsetvli_global_3 + ; CHECK: bb.0 (%ir-block.0): + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: PseudoBR %bb.2 + ; CHECK: bb.1: + ; CHECK: successors: %bb.2(0x80000000) + ; CHECK: dead %0:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: bb.2: + ; CHECK: dead %1:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoRET + bb.0 (%ir-block.0): + PseudoBR %bb.2 + bb.1: + dead %10:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + bb.2: + dead %20:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoRET +... +--- +# Check that the config doesn't match if it is following a CALL instuction. +name: cleanup_vsetvli_global_4 +alignment: 4 +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: cleanup_vsetvli_global_4 + ; CHECK: bb.0 (%ir-block.0): + ; CHECK: successors: %bb.1(0x80000000) + ; CHECK: dead %0:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: bb.1: + ; CHECK: PseudoCALL @cleanup_vsetvli_global_4 + ; CHECK: dead %1:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoRET + bb.0 (%ir-block.0): + dead %0:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + bb.1: + PseudoCALL @cleanup_vsetvli_global_4 + dead %10:gpr = PseudoVSETIVLI 4, 88, implicit-def $vl, implicit-def $vtype + PseudoRET +... diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-ctlz.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-ctlz.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-ctlz.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-ctlz.ll @@ -3723,7 +3723,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB3_3: ; LMULMAX2-RV32-NEXT: sw a5, 0(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX2-RV32-NEXT: vsrl.vx v26, v25, a6 ; LMULMAX2-RV32-NEXT: vmv.x.s a1, v26 @@ -3956,7 +3955,6 @@ ; LMULMAX1-RV32-NEXT: srli a5, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB3_3: ; LMULMAX1-RV32-NEXT: sw a5, 0(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX1-RV32-NEXT: vsrl.vx v26, v25, a6 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v26 @@ -11176,7 +11174,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_3: ; LMULMAX2-RV32-NEXT: sw a5, 0(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v28, v26, 3 ; LMULMAX2-RV32-NEXT: vsrl.vx v30, v28, a6 ; LMULMAX2-RV32-NEXT: vmv.x.s a1, v30 @@ -11234,7 +11231,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_6: ; LMULMAX2-RV32-NEXT: sw a5, 24(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v28, v26, 2 ; LMULMAX2-RV32-NEXT: vsrl.vx v30, v28, a6 ; LMULMAX2-RV32-NEXT: vmv.x.s a1, v30 @@ -11292,7 +11288,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_9: ; LMULMAX2-RV32-NEXT: sw a5, 16(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v26, v26, 1 ; LMULMAX2-RV32-NEXT: vsrl.vx v28, v26, a6 ; LMULMAX2-RV32-NEXT: vmv.x.s a1, v28 @@ -11600,7 +11595,6 @@ ; LMULMAX1-RV32-NEXT: srli a1, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB7_3: ; LMULMAX1-RV32-NEXT: sw a1, 16(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v26, v26, 1 ; LMULMAX1-RV32-NEXT: vsrl.vx v27, v26, a7 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v27 @@ -11660,7 +11654,6 @@ ; LMULMAX1-RV32-NEXT: sw a1, 24(sp) ; LMULMAX1-RV32-NEXT: sw zero, 12(sp) ; LMULMAX1-RV32-NEXT: sw zero, 4(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vsrl.vx v26, v25, a7 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v26 ; LMULMAX1-RV32-NEXT: vmv.x.s a2, v25 @@ -11717,7 +11710,6 @@ ; LMULMAX1-RV32-NEXT: srli a1, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB7_9: ; LMULMAX1-RV32-NEXT: sw a1, 0(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX1-RV32-NEXT: vsrl.vx v26, v25, a7 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v26 diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-cttz.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-cttz.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-cttz.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-cttz.ll @@ -2587,7 +2587,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB3_3: ; LMULMAX2-RV32-NEXT: sw a5, 0(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX2-RV32-NEXT: vmv.x.s a5, v25 ; LMULMAX2-RV32-NEXT: vsrl.vx v25, v25, a6 @@ -2768,7 +2767,6 @@ ; LMULMAX1-RV32-NEXT: srli a5, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB3_3: ; LMULMAX1-RV32-NEXT: sw a5, 0(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX1-RV32-NEXT: vmv.x.s a5, v25 ; LMULMAX1-RV32-NEXT: vsrl.vx v25, v25, a6 @@ -7696,7 +7694,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_3: ; LMULMAX2-RV32-NEXT: sw a5, 0(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v28, v26, 3 ; LMULMAX2-RV32-NEXT: vmv.x.s a5, v28 ; LMULMAX2-RV32-NEXT: vsrl.vx v28, v28, a6 @@ -7738,7 +7735,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_6: ; LMULMAX2-RV32-NEXT: sw a5, 24(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v28, v26, 2 ; LMULMAX2-RV32-NEXT: vmv.x.s a5, v28 ; LMULMAX2-RV32-NEXT: vsrl.vx v28, v28, a6 @@ -7780,7 +7776,6 @@ ; LMULMAX2-RV32-NEXT: srli a5, a1, 24 ; LMULMAX2-RV32-NEXT: .LBB7_9: ; LMULMAX2-RV32-NEXT: sw a5, 16(sp) -; LMULMAX2-RV32-NEXT: vsetivli a1, 1, e64,m2,ta,mu ; LMULMAX2-RV32-NEXT: vslidedown.vi v26, v26, 1 ; LMULMAX2-RV32-NEXT: vmv.x.s a5, v26 ; LMULMAX2-RV32-NEXT: vsrl.vx v26, v26, a6 @@ -8016,7 +8011,6 @@ ; LMULMAX1-RV32-NEXT: srli a1, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB7_3: ; LMULMAX1-RV32-NEXT: sw a1, 16(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v26, v26, 1 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v26 ; LMULMAX1-RV32-NEXT: vsrl.vx v26, v26, a7 @@ -8060,7 +8054,6 @@ ; LMULMAX1-RV32-NEXT: sw a1, 24(sp) ; LMULMAX1-RV32-NEXT: sw zero, 12(sp) ; LMULMAX1-RV32-NEXT: sw zero, 4(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vsrl.vx v26, v25, a7 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v25 ; LMULMAX1-RV32-NEXT: vmv.x.s a2, v26 @@ -8101,7 +8094,6 @@ ; LMULMAX1-RV32-NEXT: srli a1, a1, 24 ; LMULMAX1-RV32-NEXT: .LBB7_9: ; LMULMAX1-RV32-NEXT: sw a1, 0(sp) -; LMULMAX1-RV32-NEXT: vsetivli a1, 1, e64,m1,ta,mu ; LMULMAX1-RV32-NEXT: vslidedown.vi v25, v25, 1 ; LMULMAX1-RV32-NEXT: vmv.x.s a1, v25 ; LMULMAX1-RV32-NEXT: vsrl.vx v25, v25, a7 diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int.ll @@ -3959,7 +3959,6 @@ ; LMULMAX2-NEXT: vsetivli a2, 4, e64,m2,ta,mu ; LMULMAX2-NEXT: vle64.v v26, (a0) ; LMULMAX2-NEXT: vle64.v v28, (a1) -; LMULMAX2-NEXT: vsetivli a1, 4, e64,m2,ta,mu ; LMULMAX2-NEXT: vadd.vv v26, v26, v28 ; LMULMAX2-NEXT: vse64.v v26, (a0) ; LMULMAX2-NEXT: ret @@ -3973,7 +3972,6 @@ ; LMULMAX1-NEXT: vle64.v v27, (a1) ; LMULMAX1-NEXT: addi a1, a1, 16 ; LMULMAX1-NEXT: vle64.v v28, (a1) -; LMULMAX1-NEXT: vsetivli a1, 2, e64,m1,ta,mu ; LMULMAX1-NEXT: vadd.vv v26, v26, v28 ; LMULMAX1-NEXT: vadd.vv v25, v25, v27 ; LMULMAX1-NEXT: vse64.v v25, (a0)