[llvm] 2da5882 - [TableGen] Allow identical MnemonicAliases with no predicate

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 30 02:53:46 PDT 2021


Author: Jay Foad
Date: 2021-06-30T10:53:39+01:00
New Revision: 2da58826a5e0716163d3b91afcde1218a211d714

URL: https://github.com/llvm/llvm-project/commit/2da58826a5e0716163d3b91afcde1218a211d714
DIFF: https://github.com/llvm/llvm-project/commit/2da58826a5e0716163d3b91afcde1218a211d714.diff

LOG: [TableGen] Allow identical MnemonicAliases with no predicate

My use case for this is illustrated in the test case: I want to define
the same instruction twice with different (disjoint) predicates, because
the instruction has different operands on different subtargets. It's
convenient to do this with a multiclass that also defines an alias for
the instruction.

Previously tablegen would complain if this alias was defined twice with
no predicate. One way to fix this would be to add a predicate on each
definition of the alias, matching the predicate on the instruction. But
this (a) is slightly awkward to do in the real world use case I had, and
(b) leads to an inefficient matcher that will do something like this:

  if (Mnemonic == "foo_alias") {
    if (Features.test(Feature_Subtarget1Bit))
      Mnemonic == "foo";
    else if (Features.test(Feature_Subtarget2Bit))
      Mnemonic == "foo";
    return;
  }

It would be more efficient to skip the feature tests and return "foo"
unconditionally.

Overall it seems better to allow multiple definitions of the identical
alias with no predicate.

Differential Revision: https://reviews.llvm.org/D105033

Added: 
    llvm/test/TableGen/MnemonicAlias.td

Modified: 
    llvm/utils/TableGen/AsmMatcherEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/TableGen/MnemonicAlias.td b/llvm/test/TableGen/MnemonicAlias.td
new file mode 100644
index 0000000000000..518454a7ca63f
--- /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<string name, dag outs, dag ins, Predicate pred> {
+  def "" : Instruction {
+    let Size = 2;
+    let OutOperandList = outs;
+    let InOperandList = ins;
+    let AsmString = name;
+    let Predicates = [pred];
+  }
+  def : MnemonicAlias<name # "_alias", name>;
+}
+
+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 96159a60c665a..00bdd127e3c28 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 
diff erent aliases from the same mnemonic with no
+          // predicate.
+          PrintError(
+              ToVec[AliasWithNoPredicate]->getLoc(),
+              "two 
diff erent MnemonicAliases with the same 'from' mnemonic!");
           PrintFatalError(R->getLoc(), "this is the other MnemonicAlias.");
         }
 


        


More information about the llvm-commits mailing list