From bef419a7786bf14a644daa3ef407d38a65cddaab Mon Sep 17 00:00:00 2001 From: Sjoerd Meijer Date: Thu, 30 May 2019 07:38:09 +0000 Subject: [PATCH] [TableGen] AsmMatcher: allow repeated input operands If an assembly instruction has to mention an input operand name twice, for example the MVE VMOV instruction that accesses two lanes of the same vector by writing 'vmov r1, r2, q0[3], q0[1]', then the obvious way to write its AsmString is to include the same operand (here $Qd) twice. But this causes the AsmMatcher generator to omit that instruction completely from the match table, on the basis that the generator isn't clever enough to deal with the duplication. But you need to have _some_ way of dealing with an instruction like this - and in this case, where the mnemonic is shared with many other instructions that the AsmMatcher does handle, it would be very painful to take it out of the AsmMatcher system completely. A nicer way is to add a custom AsmMatchConverter routine, and let that deal with the problem if the autogenerated converter can't. But that doesn't work, because TableGen leaves the instruction out of its table _even_ if you provide a custom converter. Solution: this change, which makes TableGen relax the restriction on duplicated operands in the case where there's a custom converter. Patch by: Simon Tatham Differential Revision: https://reviews.llvm.org/D60695 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362066 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 1229b65b24b..146d10835b8 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1072,8 +1072,9 @@ bool MatchableInfo::validate(StringRef CommentDelimiter, bool IsAlias) const { // handle, the target should be refactored to use operands instead of // modifiers. // - // Also, check for instructions which reference the operand multiple times; - // this implies a constraint we would not honor. + // Also, check for instructions which reference the operand multiple times, + // if they don't define a custom AsmMatcher: this implies a constraint that + // the built-in matching code would not honor. std::set OperandNames; for (const AsmOperand &Op : AsmOperands) { StringRef Tok = Op.Token; @@ -1083,7 +1084,8 @@ bool MatchableInfo::validate(StringRef CommentDelimiter, bool IsAlias) const { "' not supported by asm matcher. Mark isCodeGenOnly!"); // Verify that any operand is only mentioned once. // We reject aliases and ignore instructions for now. - if (!IsAlias && Tok[0] == '$' && !OperandNames.insert(Tok).second) { + if (!IsAlias && TheDef->getValueAsString("AsmMatchConverter").empty() && + Tok[0] == '$' && !OperandNames.insert(Tok).second) { LLVM_DEBUG({ errs() << "warning: '" << TheDef->getName() << "': " << "ignoring instruction with tied operand '" -- 2.11.0