diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2015-09-10 14:04:34 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2015-09-10 14:04:34 +0000 |
| commit | 0153e59935cb14302e01e5546afc00a2575ecbf8 (patch) | |
| tree | af334c15d80c3b39bf1ca1868fa1bfd90c349f08 /llvm/lib/CodeGen | |
| parent | 3285f1b850b736f507772b64b1a16e55fe2c1afc (diff) | |
| download | bcm5719-llvm-0153e59935cb14302e01e5546afc00a2575ecbf8.tar.gz bcm5719-llvm-0153e59935cb14302e01e5546afc00a2575ecbf8.zip | |
Fix PR 24724 - The implicit register verifier shouldn't assume certain operand
order.
The implicit register verifier in the MIR parser should only check if the
instruction's default implicit operands are present in the instruction. It
should not check the order in which they occur.
llvm-svn: 247283
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 55 |
1 files changed, 16 insertions, 39 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index c09f279a25f..5a8e96df760 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -724,6 +724,16 @@ static std::string getRegisterName(const TargetRegisterInfo *TRI, return StringRef(TRI->getName(Reg)).lower(); } +/// Return true if the parsed machine operands contain a given machine operand. +static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand, + ArrayRef<ParsedMachineOperand> Operands) { + for (const auto &I : Operands) { + if (ImplicitOperand.isIdenticalTo(I.Operand)) + return true; + } + return false; +} + bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, const MCInstrDesc &MCID) { if (MCID.isCall()) @@ -744,46 +754,13 @@ bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, const auto *TRI = MF.getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); - size_t I = ImplicitOperands.size(), J = Operands.size(); - while (I) { - --I; - if (J) { - --J; - const auto &ImplicitOperand = ImplicitOperands[I]; - const auto &Operand = Operands[J].Operand; - if (ImplicitOperand.isIdenticalTo(Operand)) - continue; - if (Operand.isReg() && Operand.isImplicit()) { - // Check if this implicit register is a subregister of an explicit - // register operand. - bool IsImplicitSubRegister = false; - for (size_t K = 0, E = Operands.size(); K < E; ++K) { - const auto &Op = Operands[K].Operand; - if (Op.isReg() && !Op.isImplicit() && - TRI->isSubRegister(Op.getReg(), Operand.getReg())) { - IsImplicitSubRegister = true; - break; - } - } - if (IsImplicitSubRegister) - continue; - return error(Operands[J].Begin, - Twine("expected an implicit register operand '") + - printImplicitRegisterFlag(ImplicitOperand) + " %" + - getRegisterName(TRI, ImplicitOperand.getReg()) + "'"); - } - } - // TODO: Fix source location when Operands[J].end is right before '=', i.e: - // insead of reporting an error at this location: - // %eax = MOV32r0 - // ^ - // report the error at the following location: - // %eax = MOV32r0 - // ^ - return error(J < Operands.size() ? Operands[J].End : Token.location(), + for (const auto &I : ImplicitOperands) { + if (isImplicitOperandIn(I, Operands)) + continue; + return error(Operands.empty() ? Token.location() : Operands.back().End, Twine("missing implicit register operand '") + - printImplicitRegisterFlag(ImplicitOperands[I]) + " %" + - getRegisterName(TRI, ImplicitOperands[I].getReg()) + "'"); + printImplicitRegisterFlag(I) + " %" + + getRegisterName(TRI, I.getReg()) + "'"); } return false; } |

