diff --git a/llvm/test/TableGen/MnemonicAlias.td b/llvm/test/TableGen/MnemonicAlias.td new file mode 100644 index 000000000000..518454a7ca63 --- /dev/null +++ b/llvm/test/TableGen/MnemonicAlias.td @@ -0,0 +1,41 @@ +// RUN: llvm-tblgen -gen-asm-matcher -I %p/../../include %s | FileCheck %s + +include "llvm/Target/Target.td" + +def ArchInstrInfo : InstrInfo { } + +def Arch : Target { + let InstructionSet = ArchInstrInfo; +} + +def Reg : Register<"reg">; +def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>; + +def AsmCond1 : SubtargetFeature<"cond1", "cond1", "true", "">; +def AsmCond2 : SubtargetFeature<"cond2", "cond2", "true", "">; + +def Subtarget1 : Predicate<"Pred1">, AssemblerPredicate<(all_of AsmCond1)>; +def Subtarget2 : Predicate<"Pred2">, AssemblerPredicate<(all_of AsmCond2)>; + +multiclass DefInstruction { + def "" : Instruction { + let Size = 2; + let OutOperandList = outs; + let InOperandList = ins; + let AsmString = name; + let Predicates = [pred]; + } + def : MnemonicAlias; +} + +defm FooInst1 : DefInstruction<"foo", (outs), (ins), Subtarget1>; + +defm FooInst2 : DefInstruction<"foo", (outs), (ins), Subtarget2>; + +// Check that applyMnemonicAliases maps "foo_alias" to "foo" once only and +// without checking any predicates. + +// CHECK: if (memcmp(Mnemonic.data()+0, "foo_alias", 9) != 0) +// CHECK-NEXT: break; +// CHECK-NEXT: Mnemonic = "foo"; // "foo_alias" +// CHECK-NEXT: return; diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 96159a60c665..00bdd127e3c2 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -2749,10 +2749,14 @@ static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info, // If this unconditionally matches, remember it for later and diagnose // duplicates. if (FeatureMask.empty()) { - if (AliasWithNoPredicate != -1) { - // We can't have two aliases from the same mnemonic with no predicate. - PrintError(ToVec[AliasWithNoPredicate]->getLoc(), - "two MnemonicAliases with the same 'from' mnemonic!"); + if (AliasWithNoPredicate != -1 && + R->getValueAsString("ToMnemonic") != + ToVec[AliasWithNoPredicate]->getValueAsString("ToMnemonic")) { + // We can't have two different aliases from the same mnemonic with no + // predicate. + PrintError( + ToVec[AliasWithNoPredicate]->getLoc(), + "two different MnemonicAliases with the same 'from' mnemonic!"); PrintFatalError(R->getLoc(), "this is the other MnemonicAlias."); }