[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