[llvm] 19f8176 - [TableGen] Add div bang operator

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 30 12:08:57 PDT 2022


Author: Michael Maitland
Date: 2022-09-30T12:08:28-07:00
New Revision: 19f8176eb6f557e62080e232ec2ef107ab363dde

URL: https://github.com/llvm/llvm-project/commit/19f8176eb6f557e62080e232ec2ef107ab363dde
DIFF: https://github.com/llvm/llvm-project/commit/19f8176eb6f557e62080e232ec2ef107ab363dde.diff

LOG: [TableGen] Add div bang operator

This patch adds the div bang operator which performs division.

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

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/test/TableGen/math.td

Removed: 
    


################################################################################
diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 0bafc92ae8953..99835f98287cf 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -220,13 +220,13 @@ TableGen provides "bang operators" that have a wide variety of uses:
 .. productionlist::
    BangOperator: one of
                : !add        !and         !cast        !con         !dag
-               : !empty      !eq          !filter      !find        !foldl
-               : !foreach    !ge          !getdagop    !gt          !head
-               : !if         !interleave  !isa         !le          !listconcat
-               : !listsplat  !lt          !mul         !ne          !not
-               : !or         !setdagop    !shl         !size        !sra
-               : !srl        !strconcat   !sub         !subst       !substr
-               : !tail       !xor
+               : !div        !empty       !eq          !filter      !find
+               : !foldl      !foreach     !ge          !getdagop    !gt
+               : !head       !if          !interleave  !isa         !le
+               : !listconcat !listsplat   !lt          !mul         !ne
+               : !not        !or          !setdagop    !shl         !size
+               : !sra        !srl         !strconcat   !sub         !subst
+               : !substr     !tail        !xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1622,6 +1622,10 @@ and non-0 as true.
     Example: ``!dag(op, [a1, a2, ?], ["name1", "name2", "name3"])`` results in
     ``(op a1-value:$name1, a2-value:$name2, ?:$name3)``.
 
+``!div(``\ *a*\ ``,`` *b*\ ``)``
+    This operator preforms signed division of *a* by *b*, and produces the quotient.
+    Division by 0 produces an error. Division of INT64_MIN by -1 produces an error.
+
 ``!empty(``\ *a*\ ``)``
     This operator produces 1 if the string, list, or DAG *a* is empty; 0 otherwise.
     A dag is empty if it has no arguments; the operator does not count.

diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 2d44f39973e27..3e9e90d7802fb 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -833,9 +833,30 @@ class UnOpInit : public OpInit, public FoldingSetNode {
 /// !op (X, Y) - Combine two inits.
 class BinOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum BinaryOp : uint8_t { ADD, SUB, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
-                            LISTSPLAT, STRCONCAT, INTERLEAVE, CONCAT, EQ,
-                            NE, LE, LT, GE, GT, SETDAGOP };
+  enum BinaryOp : uint8_t {
+    ADD,
+    SUB,
+    MUL,
+    DIV,
+    AND,
+    OR,
+    XOR,
+    SHL,
+    SRA,
+    SRL,
+    LISTCONCAT,
+    LISTSPLAT,
+    STRCONCAT,
+    INTERLEAVE,
+    CONCAT,
+    EQ,
+    NE,
+    LE,
+    LT,
+    GE,
+    GT,
+    SETDAGOP
+  };
 
 private:
   Init *LHS, *RHS;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 053322ed0ca52..5f706ea2893a1 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1165,6 +1165,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
   case ADD:
   case SUB:
   case MUL:
+  case DIV:
   case AND:
   case OR:
   case XOR:
@@ -1183,6 +1184,16 @@ Init *BinOpInit::Fold(Record *CurRec) const {
       case ADD: Result = LHSv + RHSv; break;
       case SUB: Result = LHSv - RHSv; break;
       case MUL: Result = LHSv * RHSv; break;
+      case DIV:
+        if (RHSv == 0)
+          PrintFatalError(CurRec->getLoc(),
+                          "Illegal operation: division by zero");
+        else if (LHSv == INT64_MIN && RHSv == -1)
+          PrintFatalError(CurRec->getLoc(),
+                          "Illegal operation: INT64_MIN / -1");
+        else
+          Result = LHSv / RHSv;
+        break;
       case AND: Result = LHSv & RHSv; break;
       case OR:  Result = LHSv | RHSv; break;
       case XOR: Result = LHSv ^ RHSv; break;
@@ -1215,6 +1226,7 @@ std::string BinOpInit::getAsString() const {
   case ADD: Result = "!add"; break;
   case SUB: Result = "!sub"; break;
   case MUL: Result = "!mul"; break;
+  case DIV: Result = "!div"; break;
   case AND: Result = "!and"; break;
   case OR: Result = "!or"; break;
   case XOR: Result = "!xor"; break;

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index 65959b2c0a0c1..c7c8ffe51f67c 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -567,6 +567,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
     .Case("add", tgtok::XADD)
     .Case("sub", tgtok::XSUB)
     .Case("mul", tgtok::XMUL)
+    .Case("div", tgtok::XDIV)
     .Case("not", tgtok::XNOT)
     .Case("and", tgtok::XAND)
     .Case("or", tgtok::XOR)

diff  --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 9ba66b7a5622f..a1c08fe5bd224 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -52,7 +52,7 @@ namespace tgtok {
     String, Then, TrueKW,
 
     // Bang operators.
-    XConcat, XADD, XSUB, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
+    XConcat, XADD, XSUB, XMUL, XDIV, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
     XListConcat, XListSplat, XStrConcat, XInterleave, XSubstr, XFind, XCast,
     XSubst, XForEach, XFilter, 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 a574d20a75e9b..4608d892f2320 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1159,6 +1159,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
   case tgtok::XADD:
   case tgtok::XSUB:
   case tgtok::XMUL:
+  case tgtok::XDIV:
   case tgtok::XAND:
   case tgtok::XOR:
   case tgtok::XXOR:
@@ -1187,6 +1188,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     case tgtok::XADD:    Code = BinOpInit::ADD; break;
     case tgtok::XSUB:    Code = BinOpInit::SUB; break;
     case tgtok::XMUL:    Code = BinOpInit::MUL; break;
+    case tgtok::XDIV:    Code = BinOpInit::DIV; break;
     case tgtok::XAND:    Code = BinOpInit::AND; break;
     case tgtok::XOR:     Code = BinOpInit::OR; break;
     case tgtok::XXOR:    Code = BinOpInit::XOR; break;
@@ -1225,6 +1227,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
     case tgtok::XADD:
     case tgtok::XSUB:
     case tgtok::XMUL:
+    case tgtok::XDIV:
       Type = IntRecTy::get(Records);
       ArgType = IntRecTy::get(Records);
       break;
@@ -1384,7 +1387,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
             Code != BinOpInit::AND && Code != BinOpInit::OR &&
             Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
             Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
-            Code != BinOpInit::MUL)
+            Code != BinOpInit::MUL && Code != BinOpInit::DIV)
           ArgType = Resolved;
       }
 
@@ -2139,6 +2142,7 @@ Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
 ///   SimpleValue ::= '(' IDValue DagArgList ')'
 ///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= ADDTOK '(' Value ',' Value ')'
+///   SimpleValue ::= DIVTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SUBTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
@@ -2427,6 +2431,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
   case tgtok::XADD:
   case tgtok::XSUB:
   case tgtok::XMUL:
+  case tgtok::XDIV:
   case tgtok::XNOT:
   case tgtok::XAND:
   case tgtok::XOR:

diff  --git a/llvm/test/TableGen/math.td b/llvm/test/TableGen/math.td
index 4b9b3ae04dfc6..07cfb33532834 100644
--- a/llvm/test/TableGen/math.td
+++ b/llvm/test/TableGen/math.td
@@ -1,4 +1,6 @@
 // RUN: llvm-tblgen %s | FileCheck %s
+// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
+// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
 // XFAIL: vg_leak
 
 // CHECK: def shifts
@@ -47,6 +49,36 @@ def v1025   : Int<!add(int1024.Value, 1)>;
 // CHECK: Value = 12
 def v12   : Int<!mul(4, 3)>;
 
+// CHECK: def v13
+// CHECK: Value = 5
+def v13   : Int<!div(10, 2)>;
+
+// CHECK: def v14
+// CHECK: Value = 5
+def v14 : Int<!div(11, 2)>;
+
+// CHECK: def v15
+// CHECK: Value = 1
+def v15 : Int<!div(1, 1)>;
+
+// CHECK: def v16
+// CHECK: Value = 0
+def v16 : Int<!div(0, 10)>;
+
+// CHECK: def v17
+// CHECK: Value = -2
+def v17 : Int<!div(-8, 4)>;
+
+#ifdef ERROR1
+// ERROR1: error: Illegal operation: division by zero
+def v18 : Int<!div(4, 0)>;
+#endif
+
+#ifdef ERROR2
+// ERROR2: error: Illegal operation: INT64_MIN / -1
+def v19 : Int<!div(-9223372036854775808, -1)>;
+#endif
+
 // CHECK: def v1a
 // CHECK: Value = 1
 


        


More information about the llvm-commits mailing list