[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