[llvm] 9d72065 - [TableGen] [AMDGPU] Add !sub operator for subtraction

Paul C. Anagnostopoulos via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 28 09:28:27 PDT 2020


Author: Paul C. Anagnostopoulos
Date: 2020-10-28T12:27:53-04:00
New Revision: 9d72065cf6e0d02f748671d872d891f36ceda257

URL: https://github.com/llvm/llvm-project/commit/9d72065cf6e0d02f748671d872d891f36ceda257
DIFF: https://github.com/llvm/llvm-project/commit/9d72065cf6e0d02f748671d872d891f36ceda257.diff

LOG: [TableGen] [AMDGPU] Add !sub operator for subtraction

Use it in the AMDGPU target to eliminate !add(value1, !mul(value2, -1))

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

Added: 
    

Modified: 
    llvm/docs/TableGen/ProgRef.rst
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGLexer.cpp
    llvm/lib/TableGen/TGLexer.h
    llvm/lib/TableGen/TGParser.cpp
    llvm/lib/Target/AMDGPU/SIRegisterInfo.td
    llvm/test/TableGen/arithmetic.td
    llvm/test/TableGen/math.td

Removed: 
    


################################################################################
diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 742c7228d4eb..47fac8d2a858 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -214,8 +214,8 @@ TableGen provides "bang operators" that have a wide variety of uses:
                : !getdagop   !gt          !head        !if          !isa
                : !le         !listconcat  !listsplat   !lt          !mul
                : !ne         !not         !or          !setdagop    !shl
-               : !size       !sra         !srl         !strconcat   !subst
-               : !tail       !xor
+               : !size       !sra         !srl         !strconcat   !sub
+               : !subst      !tail        !xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1663,6 +1663,9 @@ and non-0 as true.
     are not strings, in which
     case an implicit ``!cast<string>`` is done on those operands.
 
+``!sub(``\ *a*\ ``,`` *b*\ ``)``
+    This operator subtracts *b* from *a* and produces the arithmetic 
diff erence.
+
 ``!subst(``\ *target*\ ``,`` *repl*\ ``,`` *value*\ ``)``
     This operator replaces all occurrences of the *target* in the *value* with
     the *repl* and produces the resulting value. The *value* can

diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index d28dacd0fb00..50f20c7fe814 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -808,7 +808,7 @@ class UnOpInit : public OpInit, public FoldingSetNode {
 /// !op (X, Y) - Combine two inits.
 class BinOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum BinaryOp : uint8_t { ADD, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
+  enum BinaryOp : uint8_t { ADD, SUB, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
                             LISTSPLAT, STRCONCAT, CONCAT, EQ, NE, LE, LT, GE,
                             GT, SETDAGOP };
 

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index b5d32b3f304d..4d39c02e20a1 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1024,6 +1024,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case ADD:
+  case SUB:
   case MUL:
   case AND:
   case OR:
@@ -1040,9 +1041,10 @@ Init *BinOpInit::Fold(Record *CurRec) const {
       int64_t Result;
       switch (getOpcode()) {
       default: llvm_unreachable("Bad opcode!");
-      case ADD: Result = LHSv +  RHSv; break;
-      case MUL: Result = LHSv *  RHSv; break;
-      case AND: Result = LHSv &  RHSv; break;
+      case ADD: Result = LHSv + RHSv; break;
+      case SUB: Result = LHSv - RHSv; break;
+      case MUL: Result = LHSv * RHSv; break;
+      case AND: Result = LHSv & RHSv; break;
       case OR:  Result = LHSv | RHSv; break;
       case XOR: Result = LHSv ^ RHSv; break;
       case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
@@ -1072,6 +1074,7 @@ std::string BinOpInit::getAsString() const {
   switch (getOpcode()) {
   case CONCAT: Result = "!con"; break;
   case ADD: Result = "!add"; break;
+  case SUB: Result = "!sub"; break;
   case MUL: Result = "!mul"; break;
   case AND: Result = "!and"; break;
   case OR: Result = "!or"; break;

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index 022b58c992a7..9533624a0ae8 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -562,6 +562,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
     .Case("con", tgtok::XConcat)
     .Case("dag", tgtok::XDag)
     .Case("add", tgtok::XADD)
+    .Case("sub", tgtok::XSUB)
     .Case("mul", tgtok::XMUL)
     .Case("not", tgtok::XNOT)
     .Case("and", tgtok::XAND)

diff  --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index b9b68f7a10ba..405592d6554d 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -51,7 +51,7 @@ namespace tgtok {
     MultiClass, String, Defset, Defvar, If, Then, ElseKW,
 
     // !keywords.
-    XConcat, XADD, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
+    XConcat, XADD, XSUB, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
     XListConcat, XListSplat, XStrConcat, XCast, XSubst, XForEach, XFoldl,
     XHead, XTail, XSize, XEmpty, XIf, XCond, XEq, XIsA, XDag, XNe, XLe,
     XLt, XGe, XGt, XSetDagOp, XGetDagOp,

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index e456dfc3b181..fcb007127772 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1075,6 +1075,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
 
   case tgtok::XConcat:
   case tgtok::XADD:
+  case tgtok::XSUB:
   case tgtok::XMUL:
   case tgtok::XAND:
   case tgtok::XOR:
@@ -1101,6 +1102,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     default: llvm_unreachable("Unhandled code!");
     case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
     case tgtok::XADD:    Code = BinOpInit::ADD; break;
+    case tgtok::XSUB:    Code = BinOpInit::SUB; break;
     case tgtok::XMUL:    Code = BinOpInit::MUL; break;
     case tgtok::XAND:    Code = BinOpInit::AND; break;
     case tgtok::XOR:     Code = BinOpInit::OR; break;
@@ -1137,6 +1139,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     case tgtok::XSRL:
     case tgtok::XSHL:
     case tgtok::XADD:
+    case tgtok::XSUB:
     case tgtok::XMUL:
       Type = IntRecTy::get();
       ArgType = IntRecTy::get();
@@ -1249,10 +1252,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
                              ListType->getAsString() + "'");
           return nullptr;
         }
-        if (Code != BinOpInit::ADD && Code != BinOpInit::AND &&
-            Code != BinOpInit::OR && Code != BinOpInit::XOR &&
-            Code != BinOpInit::SRA && Code != BinOpInit::SRL &&
-            Code != BinOpInit::SHL && Code != BinOpInit::MUL)
+        if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
+            Code != BinOpInit::AND && Code != BinOpInit::OR &&
+            Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
+            Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
+            Code != BinOpInit::MUL)
           ArgType = Resolved;
       }
 
@@ -1799,6 +1803,7 @@ Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
 ///   SimpleValue ::= '(' IDValue DagArgList ')'
 ///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= ADDTOK '(' Value ',' Value ')'
+///   SimpleValue ::= SUBTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
@@ -2094,6 +2099,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
   case tgtok::XConcat:
   case tgtok::XDag:
   case tgtok::XADD:
+  case tgtok::XSUB:
   case tgtok::XMUL:
   case tgtok::XNOT:
   case tgtok::XAND:

diff  --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
index 4bbd39c1a8e5..bbcaf2fbfcde 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.td
@@ -27,17 +27,17 @@ let Namespace = "AMDGPU" in {
 def lo16 : SubRegIndex<16, 0>;
 def hi16 : SubRegIndex<16, 16>;
 
-foreach Index = 0-31 in {
+foreach Index = 0...31 in {
   def sub#Index : SubRegIndex<32, !shl(Index, 5)>;
 }
 
-foreach Index = 1-31 in {
+foreach Index = 1...31 in {
   def sub#Index#_lo16 : ComposedSubRegIndex<!cast<SubRegIndex>(sub#Index), lo16>;
   def sub#Index#_hi16 : ComposedSubRegIndex<!cast<SubRegIndex>(sub#Index), hi16>;
 }
 
-foreach Size = {2-6,8,16} in {
-  foreach Index = Indexes<!add(33, !mul(Size, -1))>.slice in {
+foreach Size = {2...6,8,16} in {
+  foreach Index = Indexes<!sub(33, Size)>.slice in {
     def !foldl("", Indexes<Size>.slice, acc, cur,
                !strconcat(acc#!if(!eq(acc,""),"","_"), "sub"#!add(cur, Index))) :
       SubRegIndex<!mul(Size, 32), !shl(Index, 5)> {
@@ -89,7 +89,7 @@ class getSubRegs<int size> {
 class RegSeqNames<int last_reg, int stride, int size, string prefix,
                   int start = 0> {
   int next = !add(start, stride);
-  int end_reg = !add(!add(start, size), -1);
+  int end_reg = !add(start, size, -1);
   list<string> ret =
     !if(!le(end_reg, last_reg),
         !listconcat([prefix # "[" # start # ":" # end_reg # "]"],
@@ -102,7 +102,7 @@ class RegSeqDags<RegisterClass RC, int last_reg, int stride, int size,
                 int start = 0> {
   dag trunc_rc = (trunc RC,
                   !if(!and(!eq(stride, 1), !eq(start, 0)),
-                      !add(!add(last_reg, 2), !mul(size, -1)),
+                      !sub(!add(last_reg, 2), size),
                       !add(last_reg, 1)));
   list<dag> ret =
     !if(!lt(start, size),
@@ -247,7 +247,7 @@ def TMA : RegisterWithSubRegs<"tma", [TMA_LO, TMA_HI]> {
   let HWEncoding = 110;
 }
 
-foreach Index = 0-15 in {
+foreach Index = 0...15 in {
   defm TTMP#Index#_vi         : SIRegLoHi16<"ttmp"#Index, !add(112, Index)>;
   defm TTMP#Index#_gfx9_gfx10 : SIRegLoHi16<"ttmp"#Index, !add(108, Index)>;
   defm TTMP#Index             : SIRegLoHi16<"ttmp"#Index, 0>;
@@ -274,7 +274,7 @@ def FLAT_SCR_vi : FlatReg<FLAT_SCR_LO_vi, FLAT_SCR_HI_vi, 102>;
 def FLAT_SCR : FlatReg<FLAT_SCR_LO, FLAT_SCR_HI, 0>;
 
 // SGPR registers
-foreach Index = 0-105 in {
+foreach Index = 0...105 in {
   defm SGPR#Index :
      SIRegLoHi16 <"s"#Index, Index>,
      DwarfRegNum<[!if(!le(Index, 63), !add(Index, 32), !add(Index, 1024)),
@@ -282,14 +282,14 @@ foreach Index = 0-105 in {
 }
 
 // VGPR registers
-foreach Index = 0-255 in {
+foreach Index = 0...255 in {
   defm VGPR#Index :
     SIRegLoHi16 <"v"#Index, Index, 0, 1>,
     DwarfRegNum<[!add(Index, 2560), !add(Index, 1536)]>;
 }
 
 // AccVGPR registers
-foreach Index = 0-255 in {
+foreach Index = 0...255 in {
   defm AGPR#Index :
       SIRegLoHi16 <"a"#Index, Index, 1, 1>,
       DwarfRegNum<[!add(Index, 3072), !add(Index, 2048)]>;
@@ -389,7 +389,7 @@ def TTMP_512Regs : SIRegisterTuples<getSubRegs<16>.ret, TTMP_32, 15, 4, 16, "ttm
 class TmpRegTuplesBase<int index, int size,
                        list<Register> subRegs,
                        list<SubRegIndex> indices = getSubRegs<size>.ret,
-                       int index1 = !add(index, !add(size, -1)),
+                       int index1 = !add(index, size, -1),
                        string name = "ttmp["#index#":"#index1#"]"> :
   RegisterWithSubRegs<name, subRegs> {
   let HWEncoding = subRegs[0].HWEncoding;

diff  --git a/llvm/test/TableGen/arithmetic.td b/llvm/test/TableGen/arithmetic.td
index db268eef2f85..93c601331366 100644
--- a/llvm/test/TableGen/arithmetic.td
+++ b/llvm/test/TableGen/arithmetic.td
@@ -4,24 +4,32 @@
 // CHECK: --- Defs ---
 
 // CHECK: def A0 {
-// CHECK:   bits<8> add = { 0, 1, 0, 0, 0, 0, 0, 0 };
+// CHECK:   bits<8> add = { 0, 0, 0, 1, 1, 0, 0, 0 };
+// CHECK:   bits<8> sub = { 0, 0, 0, 1, 0, 0, 1, 0 };
 // CHECK:   bits<8> and = { 0, 0, 0, 0, 0, 0, 0, 1 };
-// CHECK:   bits<8> or =  { 0, 0, 1, 1, 1, 1, 1, 1 };
-// CHECK:   bits<8> xor = { 0, 0, 1, 1, 1, 1, 1, 0 };
-// CHECK:   bits<8> srl = { 0, 0, 0, 1, 1, 1, 1, 1 };
-// CHECK:   bits<8> sra = { 0, 0, 0, 1, 1, 1, 1, 1 };
-// CHECK:   bits<8> shl = { 0, 1, 1, 1, 1, 1, 1, 0 };
-// CHECK: }
+// CHECK:   bits<8> or = { 0, 0, 0, 1, 0, 1, 1, 1 };
+// CHECK:   bits<8> xor = { 0, 0, 0, 1, 0, 1, 1, 0 };
+// CHECK:   bits<8> srl = { 0, 0, 0, 0, 0, 0, 1, 0 };
+// CHECK:   bits<8> sra = { 0, 0, 0, 0, 0, 0, 1, 0 };
+// CHECK:   bits<8> shl = { 1, 0, 1, 0, 1, 0, 0, 0 };
+
+// CHECK:   bits<8> sra = { 1, 1, 1, 1, 1, 1, 1, 1 };
 
 class A<bits<8> a, bits<2> b> {
   // Operands of 
diff erent bits types are allowed.
   bits<8> add = !add(a, b);
+  bits<8> sub = !sub(a, b);
   bits<8> and = !and(a, b);
-  bits<8> or = !or(a, b);
+  bits<8> or =  !or(a, b);
   bits<8> xor = !xor(a, b);
   bits<8> srl = !srl(a, b);
   bits<8> sra = !sra(a, b);
   bits<8> shl = !shl(a, b);
 }
 
-def A0 : A<63, 1>;
+def A0 : A<21, 3>;
+
+def A1 {
+  bits<8> sra = !sra(-1, 3);
+}
+

diff  --git a/llvm/test/TableGen/math.td b/llvm/test/TableGen/math.td
index 24a0e53a7916..4b9b3ae04dfc 100644
--- a/llvm/test/TableGen/math.td
+++ b/llvm/test/TableGen/math.td
@@ -1,37 +1,45 @@
 // RUN: llvm-tblgen %s | FileCheck %s
 // XFAIL: vg_leak
 
+// CHECK: def shifts
+// CHECK: shifted_b = 8
+// CHECK: shifted_i = 8
 def shifts {
     bits<2> b = 0b10;
     int i = 2;
     int shifted_b = !shl(b, 2);
     int shifted_i = !shl(i, 2);
 }
-// CHECK: def shifts
-// CHECK: shifted_b = 8
-// CHECK: shifted_i = 8
 
 class Int<int value> {
   int Value = value;
 }
 
-def v1022   : Int<1022>;
+def int2 : Int<2>;
+def int1022 : Int<1022>;
+def int1024 : Int<1024>;
 
-// CHECK: def v0
+// CHECK: def v0a
 // CHECK: Value = 0
+def v0a : Int<!sub(int1024.Value, int1024.Value)>;
+
+// CHECK: def v0b
+// CHECK: Value = 0
+def v0b : Int<!and(int1024.Value, 2048)>;
 
 // CHECK: def v1
 // CHECK: Value = 1
+def v1 : Int<!and(1025, 1)>;
+
+// CHECK: def v1019
+// CHECK: Value = 1019
+def v1019 : Int<!sub(int1022.Value, 3)>;
 
 // CHECK: def v1023
 // CHECK: Value = 1023
-def v1023 : Int<!or(v1022.Value, 1)>;
+def v1023 : Int<!or(int1022.Value, 1)>;
 
-def v1024   : Int<1024>;
-// CHECK: def v1024
-// CHECK: Value = 1024
-
-def v1025   : Int<!add(v1024.Value, 1)>;
+def v1025   : Int<!add(int1024.Value, 1)>;
 // CHECK: def v1025
 // CHECK: Value = 1025
 
@@ -42,20 +50,13 @@ def v12   : Int<!mul(4, 3)>;
 // CHECK: def v1a
 // CHECK: Value = 1
 
-// CHECK: def v2
-// CHECK: Value = 2
-def v2 : Int<2>;
-
-def v2048   : Int<!add(v1024.Value, v1024.Value)>;
 // CHECK: def v2048
 // CHECK: Value = 2048
-
-def v0 : Int<!and(v1024.Value, v2048.Value)>;
-def v1 : Int<!and(v1025.Value, 1)>;
+def v2048   : Int<!add(int1024.Value, int1024.Value)>;
 
 // CHECK: def v3072
 // CHECK: Value = 3072
-def v3072 : Int<!or(v1024.Value, v2048.Value)>;
+def v3072 : Int<!or(int1024.Value, v2048.Value)>;
 
 // CHECK: def v4
 // CHECK: Value = 4
@@ -63,8 +64,8 @@ def v3072 : Int<!or(v1024.Value, v2048.Value)>;
 // CHECK: def v7
 // CHECK: Value = 7
 
-def v4 : Int<!add(v2.Value, 1, v1.Value)>;
-def v7 : Int<!or(v1.Value, v2.Value, v4.Value)>;
+def v4 : Int<!add(int2.Value, 1, v1.Value)>;
+def v7 : Int<!or(v1.Value, int2.Value, v4.Value)>;
 def v1a : Int<!and(v7.Value, 5, v1.Value)>;
 
 // CHECK: def v84
@@ -79,4 +80,10 @@ def v9 : Int<!xor(v7.Value, 0x0E)>;
 // CHECK: Value = 924
 def v924   : Int<!mul(v84.Value, 11)>;
 
+// CHECK: def v925
+// CHECK: Value = 925
+def v925 : Int<!sub(v924.Value, -1)>;
 
+// CHECK: def vneg
+// CHECK: Value = -2
+def vneg : Int<!sub(v925.Value, 927)>;
\ No newline at end of file


        


More information about the llvm-commits mailing list