diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -178,6 +178,26 @@ return getSEWLMULRatio() == Other.getSEWLMULRatio(); } + bool hasCompatibleVTYPE(const VSETVLIInfo &InstrInfo, bool Strict) const { + // Simple case, see if full VTYPE matches. + if (hasSameVTYPE(InstrInfo)) + return true; + + if (Strict) + return false; + + // If this is a mask reg operation, it only cares about VLMAX. + // FIXME: Mask reg operations are probably ok if "this" VLMAX is larger + // than "InstrInfo". + // FIXME: The policy bits can probably be ignored for mask reg operations. + if (InstrInfo.MaskRegOp && hasSameVLMAX(InstrInfo) && + TailAgnostic == InstrInfo.TailAgnostic && + MaskAgnostic == InstrInfo.MaskAgnostic) + return true; + + return false; + } + // Determine whether the vector instructions requirements represented by // InstrInfo are compatible with the previous vsetvli instruction represented // by this. @@ -206,23 +226,15 @@ if (!hasSameAVL(InstrInfo)) return false; - // Simple case, see if full VTYPE matches. - if (hasSameVTYPE(InstrInfo)) + if (hasCompatibleVTYPE(InstrInfo, Strict)) return true; // Strict matches must ensure a full VTYPE match. if (Strict) return false; - // If this is a mask reg operation, it only cares about VLMAX. - // FIXME: Mask reg operations are probably ok if "this" VLMAX is larger - // than "InstrInfo". - if (InstrInfo.MaskRegOp && hasSameVLMAX(InstrInfo) && - TailAgnostic == InstrInfo.TailAgnostic && - MaskAgnostic == InstrInfo.MaskAgnostic) - return true; - // Store instructions don't use the policy fields. + // TODO: Move into hasCompatibleVTYPE? if (InstrInfo.StoreOp && VLMul == InstrInfo.VLMul && SEW == InstrInfo.SEW) return true; @@ -564,7 +576,7 @@ // VSETVLI here. if (!CurInfo.isUnknown() && Require.hasAVLReg() && Require.getAVLReg().isVirtual() && !CurInfo.hasSEWLMULRatioOnly() && - Require.hasSameVTYPE(CurInfo)) { + CurInfo.hasCompatibleVTYPE(Require, /*Strict*/ false)) { if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { if (DefMI->getOpcode() == RISCV::PseudoVSETVLI || DefMI->getOpcode() == RISCV::PseudoVSETVLIX0 || diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.ll --- a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.ll @@ -77,13 +77,12 @@ ret %1 } -; FIXME the second vsetvli is unnecessary. +; Make sure we don't insert a vsetvli for the vmand instruction. define @test5( %0, %1, %2, i64 %avl) nounwind { ; CHECK-LABEL: test5: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetvli a0, a0, e64, m1, ta, mu ; CHECK-NEXT: vmseq.vv v8, v8, v9 -; CHECK-NEXT: vsetvli zero, a0, e8, mf8, ta, mu ; CHECK-NEXT: vmand.mm v0, v8, v0 ; CHECK-NEXT: ret entry: