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 @@ -1074,7 +1074,10 @@ } void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) { - VSETVLIInfo CurInfo; + VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred; + // Track whether the prefix of the block we've scanned is transparent + // (meaning has not yet changed the abstract state). + bool PrefixTransparent = true; for (MachineInstr &MI : MBB) { // If this is an explicit VSETVLI or VSETIVLI, update our state. if (isVectorConfigInstr(MI)) { @@ -1085,39 +1088,28 @@ MI.getOperand(3).setIsDead(false); MI.getOperand(4).setIsDead(false); CurInfo = getInfoForVSETVLI(MI); + PrefixTransparent = false; continue; } uint64_t TSFlags = MI.getDesc().TSFlags; if (RISCVII::hasSEWOp(TSFlags)) { VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI); - if (!CurInfo.isValid()) { - // We haven't found any vector instructions or VL/VTYPE changes yet, - // use the predecessor information. - CurInfo = BlockInfo[MBB.getNumber()].Pred; - assert(CurInfo.isValid() && "Expected a valid predecessor state."); - if (needVSETVLI(MI, NewInfo, CurInfo)) { - // If this is the first implicit state change, and the state change - // requested can be proven to produce the same register contents, we - // can skip emitting the actual state change and continue as if we - // had since we know the GPR result of the implicit state change - // wouldn't be used and VL/VTYPE registers are correct. Note that - // we *do* need to model the state as if it changed as while the - // register contents are unchanged, the abstract model can change. - if (needVSETVLIPHI(NewInfo, MBB)) - insertVSETVLI(MBB, MI, NewInfo, CurInfo); - CurInfo = NewInfo; - } - } else { - // If this instruction isn't compatible with the previous VL/VTYPE - // we need to insert a VSETVLI. - // NOTE: We can't use predecessor information for the store. We must - // treat it the same as the first phase so that we produce the correct - // vl/vtype for succesor blocks. - if (needVSETVLI(MI, NewInfo, CurInfo)) { + + // If this instruction isn't compatible with the previous VL/VTYPE + // we need to update the abstract state, and possibly insert a VSETVLI. + if (needVSETVLI(MI, NewInfo, CurInfo)) { + // If this is the first implicit state change, and the state change + // requested can be proven to produce the same register contents, we + // can skip emitting the actual state change and continue as if we + // had since we know the GPR result of the implicit state change + // wouldn't be used and VL/VTYPE registers are correct. Note that + // we *do* need to model the state as if it changed as while the + // register contents are unchanged, the abstract model can change. + if (!PrefixTransparent || needVSETVLIPHI(NewInfo, MBB)) insertVSETVLI(MBB, MI, NewInfo, CurInfo); - CurInfo = NewInfo; - } + PrefixTransparent = false; + CurInfo = NewInfo; } if (RISCVII::hasVLOp(TSFlags)) { @@ -1139,6 +1131,7 @@ if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) || MI.modifiesRegister(RISCV::VTYPE)) { CurInfo = VSETVLIInfo::getUnknown(); + PrefixTransparent = false; } }