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 @@ -536,6 +536,21 @@ } } +// Update Info to the VSETVLIInfo right after MI, Info should be the +// VSETVLIInfo of MI. +static void updateToEndStatus(VSETVLIInfo &Info, const MachineInstr &MI) { + if (RISCV::isFaultFirstLoad(MI)) { + // Update AVL to vl-output of fault first load. + Info.setAVLReg(MI.getOperand(1).getReg()); + return; + } + // If this is something that updates VL/VTYPE that we don't know about, + // set the state to unknown. + if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || + MI.modifiesRegister(RISCV::VTYPE)) + Info = VSETVLIInfo::getUnknown(); +} + static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, const MachineRegisterInfo *MRI) { VSETVLIInfo InstrInfo; @@ -965,11 +980,8 @@ } } - // If this is something that updates VL/VTYPE that we don't know about, set - // the state to unknown. - if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || - MI.modifiesRegister(RISCV::VTYPE)) - BBInfo.Change = VSETVLIInfo::getUnknown(); + // Update BBInfo.Change to the VSETVLIInfo right after MI. + updateToEndStatus(BBInfo.Change, MI); } return HadVectorOp; @@ -1134,12 +1146,8 @@ } } - // If this is something that updates VL/VTYPE that we don't know about, set - // the state to unknown. - if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || - MI.modifiesRegister(RISCV::VTYPE)) { - CurInfo = VSETVLIInfo::getUnknown(); - } + // Update CurInfo to the VSETVLIInfo right after MI. + updateToEndStatus(CurInfo, MI); } // If we reach the end of the block and our current info doesn't match the @@ -1261,11 +1269,8 @@ continue; } - // If this is something that updates VL/VTYPE that we don't know about, - // set the state to unknown. - if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || - MI.modifiesRegister(RISCV::VTYPE)) - CurInfo = VSETVLIInfo::getUnknown(); + // Update CurInfo to the VSETVLIInfo right after MI. + updateToEndStatus(CurInfo, MI); } } 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 @@ -498,8 +498,7 @@ ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: vsetvli zero, a1, e64, m1, ta, mu ; CHECK-NEXT: vle64ff.v v8, (a0) -; CHECK-NEXT: csrr a0, vl -; CHECK-NEXT: vsetvli zero, a0, e64, m1, tu, mu +; CHECK-NEXT: vsetvli zero, zero, e64, m1, tu, mu ; CHECK-NEXT: vadd.vx v8, v8, a2 ; CHECK-NEXT: ret entry: diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-modify-vl.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvli-modify-vl.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-modify-vl.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+v \ +; RUN: -target-abi=lp64d -verify-machineinstrs -< %s | FileCheck %s + +declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg) +declare { , i64 } @llvm.riscv.vleff.nxv32i8.i64(, * nocapture, i64) +declare @llvm.riscv.vmseq.nxv32i8.i8.i64(, i8, i64) +declare @llvm.riscv.vadd.nxv32i8.i8.i64(, , i8, i64) + +define @seq(i1 zeroext %cond, i8* %str, i64 %n, i8 %x) { +; CHECK-LABEL: seq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a2, e8, m4, ta, mu +; CHECK-NEXT: vle8ff.v v8, (a1) +; CHECK-NEXT: vadd.vx v8, v8, a3 +; CHECK-NEXT: vmseq.vi v0, v8, 0 +; CHECK-NEXT: ret +entry: + %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 0, i64 2) + %1 = bitcast i8* %str to * + %2 = tail call { , i64 } @llvm.riscv.vleff.nxv32i8.i64( undef, * %1, i64 %0) + %3 = extractvalue { , i64 } %2, 0 + %4 = extractvalue { , i64 } %2, 1 + %5 = tail call @llvm.riscv.vadd.nxv32i8.i8.i64( undef, %3, i8 %x, i64 %4) + %6 = tail call @llvm.riscv.vmseq.nxv32i8.i8.i64( %5, i8 0, i64 %4) + ret %6 +}