forked from OSchip/llvm-project
MIR: Start diagnosing too many operands on an instruction
Previously this would just assert which was annoying and didn't point to the specific instruction/operand.
This commit is contained in:
parent
ee5580a8eb
commit
9c7ca51b2c
|
@ -460,6 +460,16 @@ public:
|
||||||
return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
|
return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if this operand can validly be appended to an arbitrary
|
||||||
|
/// operand list. i.e. this behaves like an implicit operand.
|
||||||
|
bool isValidExcessOperand() const {
|
||||||
|
if ((isReg() && isImplicit()) || isRegMask())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Debug operands
|
||||||
|
return isMetadata() || isMCSymbol();
|
||||||
|
}
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Mutators for Register Operands
|
// Mutators for Register Operands
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -1094,11 +1094,23 @@ bool MIParser::parse(MachineInstr *&MI) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check for extraneous machine operands.
|
|
||||||
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
|
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
|
||||||
MI->setFlags(Flags);
|
MI->setFlags(Flags);
|
||||||
for (const auto &Operand : Operands)
|
|
||||||
|
unsigned NumExplicitOps = 0;
|
||||||
|
for (const auto &Operand : Operands) {
|
||||||
|
bool IsImplicitOp = Operand.Operand.isReg() && Operand.Operand.isImplicit();
|
||||||
|
if (!IsImplicitOp) {
|
||||||
|
if (!MCID.isVariadic() && NumExplicitOps >= MCID.getNumOperands() &&
|
||||||
|
!Operand.Operand.isValidExcessOperand())
|
||||||
|
return error("too many operands for instruction");
|
||||||
|
|
||||||
|
++NumExplicitOps;
|
||||||
|
}
|
||||||
|
|
||||||
MI->addOperand(MF, Operand.Operand);
|
MI->addOperand(MF, Operand.Operand);
|
||||||
|
}
|
||||||
|
|
||||||
if (assignRegisterTies(*MI, Operands))
|
if (assignRegisterTies(*MI, Operands))
|
||||||
return true;
|
return true;
|
||||||
if (PreInstrSymbol)
|
if (PreInstrSymbol)
|
||||||
|
|
|
@ -232,16 +232,12 @@ void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
bool isDebugOp = Op.getType() == MachineOperand::MO_Metadata ||
|
|
||||||
Op.getType() == MachineOperand::MO_MCSymbol;
|
|
||||||
// OpNo now points as the desired insertion point. Unless this is a variadic
|
// OpNo now points as the desired insertion point. Unless this is a variadic
|
||||||
// instruction, only implicit regs are allowed beyond MCID->getNumOperands().
|
// instruction, only implicit regs are allowed beyond MCID->getNumOperands().
|
||||||
// RegMask operands go between the explicit and implicit operands.
|
// RegMask operands go between the explicit and implicit operands.
|
||||||
assert((isImpReg || Op.isRegMask() || MCID->isVariadic() ||
|
assert((MCID->isVariadic() || OpNo < MCID->getNumOperands() ||
|
||||||
OpNo < MCID->getNumOperands() || isDebugOp) &&
|
Op.isValidExcessOperand()) &&
|
||||||
"Trying to add an operand to a machine instr that is already done!");
|
"Trying to add an operand to a machine instr that is already done!");
|
||||||
#endif
|
|
||||||
|
|
||||||
MachineRegisterInfo *MRI = getRegInfo();
|
MachineRegisterInfo *MRI = getRegInfo();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# RUN: not llc -march=amdgcn -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
---
|
||||||
|
name: extra_imm_operand
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
; CHECK: [[@LINE+3]]:18: too many operands for instruction
|
||||||
|
; CHECK-NEXT: S_ENDPGM 0, 0
|
||||||
|
; CHECK_NEXT: ^
|
||||||
|
S_ENDPGM 0, 0
|
||||||
|
|
||||||
|
...
|
|
@ -0,0 +1,12 @@
|
||||||
|
# RUN: not llc -march=amdgcn -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
---
|
||||||
|
name: extra_reg_operand
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
; CHECK: [[@LINE+3]]:29: too many operands for instruction
|
||||||
|
; S_ENDPGM 0, undef $vgpr0
|
||||||
|
; CHECK_NEXT: ^
|
||||||
|
S_ENDPGM 0, undef $vgpr0
|
||||||
|
|
||||||
|
...
|
Loading…
Reference in New Issue