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 @@ -1444,7 +1444,11 @@ MI.setDesc(NextMI->getDesc()); } MI.getOperand(2).setImm(NextMI->getOperand(2).getImm()); - ToDelete.push_back(NextMI); + // Don't delete a vsetvli if its result might be used. + Register NextVRefDef = NextMI->getOperand(0).getReg(); + if (NextVRefDef == RISCV::X0 || + (NextVRefDef.isVirtual() && MRI->use_nodbg_empty(NextVRefDef))) + ToDelete.push_back(NextMI); // fallthrough } } 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 @@ -578,6 +578,23 @@ ret %2 } +; This used to fail the machine verifier due to the vsetvli being removed +; while the add was still using it. +define i64 @bad_removal(<2 x i64> %arg) { +; CHECK-LABEL: bad_removal: +; CHECK: # %bb.0: # %bb +; CHECK-NEXT: vsetivli zero, 16, e64, m1, ta, ma +; CHECK-NEXT: vmv.x.s a0, v8 +; CHECK-NEXT: vsetivli a1, 16, e64, m1, ta, ma +; CHECK-NEXT: add a0, a0, a1 +; CHECK-NEXT: ret +bb: + %tmp = extractelement <2 x i64> %arg, i64 0 + %tmp1 = call i64 @llvm.riscv.vsetvli.i64(i64 16, i64 3, i64 0) + %tmp2 = add i64 %tmp, %tmp1 + ret i64 %tmp2 +} + declare @llvm.riscv.vadd.mask.nxv1i64.nxv1i64( , ,