Skip to content

Commit aa9ca69

Browse files
committedMar 14, 2018
TableGen: Add !ne, !le, !lt, !ge, and !gt comparisons
Change-Id: I8e2ece677268972d578a787467f7ef52a1f33a71 Differential revision: https://reviews.llvm.org/D44114 llvm-svn: 327496
1 parent b61c26e commit aa9ca69

File tree

10 files changed

+159
-17
lines changed

10 files changed

+159
-17
lines changed
 

Diff for: ‎llvm/docs/TableGen/LangIntro.rst

+7
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@ supported include:
267267
on string, int and bit objects. Use !cast<string> to compare other types of
268268
objects.
269269

270+
``!ne(a,b)``
271+
The negation of ``!eq(a,b)``.
272+
273+
``!le(a,b), !lt(a,b), !ge(a,b), !gt(a,b)``
274+
(Signed) comparison of integer values that returns bit 1 or 0 depending on
275+
the result of the comparison.
276+
270277
``!shl(a,b)`` ``!srl(a,b)`` ``!sra(a,b)``
271278
The usual shift operators. Operations are on 64-bit integers, the result
272279
is undefined for shift counts outside [0, 63].

Diff for: ‎llvm/docs/TableGen/LangRef.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ wide variety of meanings:
9999
:!add !shl !sra !srl !and
100100
:!or !empty !subst !foreach !strconcat
101101
:!cast !listconcat !size !foldl
102-
:!isa !dag
102+
:!isa !dag !le !lt !ge
103+
:!gt !ne
103104

104105

105106
Syntax

Diff for: ‎llvm/include/llvm/TableGen/Record.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ class UnOpInit : public OpInit, public FoldingSetNode {
803803
class BinOpInit : public OpInit, public FoldingSetNode {
804804
public:
805805
enum BinaryOp : uint8_t { ADD, AND, OR, SHL, SRA, SRL, LISTCONCAT,
806-
STRCONCAT, CONCAT, EQ };
806+
STRCONCAT, CONCAT, EQ, NE, LE, LT, GE, GT };
807807

808808
private:
809809
Init *LHS, *RHS;

Diff for: ‎llvm/lib/TableGen/Record.cpp

+35-10
Original file line numberDiff line numberDiff line change
@@ -898,23 +898,43 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
898898
return ConcatStringInits(LHSs, RHSs);
899899
break;
900900
}
901-
case EQ: {
901+
case EQ:
902+
case NE:
903+
case LE:
904+
case LT:
905+
case GE:
906+
case GT: {
902907
// try to fold eq comparison for 'bit' and 'int', otherwise fallback
903908
// to string objects.
904909
IntInit *L =
905-
dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()));
910+
dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get()));
906911
IntInit *R =
907-
dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get()));
912+
dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get()));
908913

909-
if (L && R)
910-
return IntInit::get(L->getValue() == R->getValue());
914+
if (L && R) {
915+
bool Result;
916+
switch (getOpcode()) {
917+
case EQ: Result = L->getValue() == R->getValue(); break;
918+
case NE: Result = L->getValue() != R->getValue(); break;
919+
case LE: Result = L->getValue() <= R->getValue(); break;
920+
case LT: Result = L->getValue() < R->getValue(); break;
921+
case GE: Result = L->getValue() >= R->getValue(); break;
922+
case GT: Result = L->getValue() > R->getValue(); break;
923+
default: llvm_unreachable("unhandled comparison");
924+
}
925+
return BitInit::get(Result);
926+
}
911927

912-
StringInit *LHSs = dyn_cast<StringInit>(LHS);
913-
StringInit *RHSs = dyn_cast<StringInit>(RHS);
928+
if (getOpcode() == EQ || getOpcode() == NE) {
929+
StringInit *LHSs = dyn_cast<StringInit>(LHS);
930+
StringInit *RHSs = dyn_cast<StringInit>(RHS);
914931

915-
// Make sure we've resolved
916-
if (LHSs && RHSs)
917-
return IntInit::get(LHSs->getValue() == RHSs->getValue());
932+
// Make sure we've resolved
933+
if (LHSs && RHSs) {
934+
bool Equal = LHSs->getValue() == RHSs->getValue();
935+
return BitInit::get(getOpcode() == EQ ? Equal : !Equal);
936+
}
937+
}
918938

919939
break;
920940
}
@@ -969,6 +989,11 @@ std::string BinOpInit::getAsString() const {
969989
case SRA: Result = "!sra"; break;
970990
case SRL: Result = "!srl"; break;
971991
case EQ: Result = "!eq"; break;
992+
case NE: Result = "!ne"; break;
993+
case LE: Result = "!le"; break;
994+
case LT: Result = "!lt"; break;
995+
case GE: Result = "!ge"; break;
996+
case GT: Result = "!gt"; break;
972997
case LISTCONCAT: Result = "!listconcat"; break;
973998
case STRCONCAT: Result = "!strconcat"; break;
974999
}

Diff for: ‎llvm/lib/TableGen/TGLexer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,11 @@ tgtok::TokKind TGLexer::LexExclaim() {
467467
tgtok::TokKind Kind =
468468
StringSwitch<tgtok::TokKind>(StringRef(Start, CurPtr - Start))
469469
.Case("eq", tgtok::XEq)
470+
.Case("ne", tgtok::XNe)
471+
.Case("le", tgtok::XLe)
472+
.Case("lt", tgtok::XLt)
473+
.Case("ge", tgtok::XGe)
474+
.Case("gt", tgtok::XGt)
470475
.Case("if", tgtok::XIf)
471476
.Case("isa", tgtok::XIsA)
472477
.Case("head", tgtok::XHead)

Diff for: ‎llvm/lib/TableGen/TGLexer.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace tgtok {
4949
// !keywords.
5050
XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast,
5151
XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty, XIf, XEq, XIsA, XDag,
52+
XNe, XLe, XLt, XGe, XGt,
5253

5354
// Integer value.
5455
IntVal,

Diff for: ‎llvm/lib/TableGen/TGParser.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
974974
case tgtok::XSRL:
975975
case tgtok::XSHL:
976976
case tgtok::XEq:
977+
case tgtok::XNe:
978+
case tgtok::XLe:
979+
case tgtok::XLt:
980+
case tgtok::XGe:
981+
case tgtok::XGt:
977982
case tgtok::XListConcat:
978983
case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')'
979984
tgtok::TokKind OpTok = Lex.getCode();
@@ -991,6 +996,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
991996
case tgtok::XSRL: Code = BinOpInit::SRL; break;
992997
case tgtok::XSHL: Code = BinOpInit::SHL; break;
993998
case tgtok::XEq: Code = BinOpInit::EQ; break;
999+
case tgtok::XNe: Code = BinOpInit::NE; break;
1000+
case tgtok::XLe: Code = BinOpInit::LE; break;
1001+
case tgtok::XLt: Code = BinOpInit::LT; break;
1002+
case tgtok::XGe: Code = BinOpInit::GE; break;
1003+
case tgtok::XGt: Code = BinOpInit::GT; break;
9941004
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
9951005
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
9961006
}
@@ -1014,8 +1024,16 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
10141024
ArgType = IntRecTy::get();
10151025
break;
10161026
case tgtok::XEq:
1027+
case tgtok::XNe:
10171028
Type = BitRecTy::get();
1018-
// ArgType for Eq is not known at this point
1029+
// ArgType for Eq / Ne is not known at this point
1030+
break;
1031+
case tgtok::XLe:
1032+
case tgtok::XLt:
1033+
case tgtok::XGe:
1034+
case tgtok::XGt:
1035+
Type = BitRecTy::get();
1036+
ArgType = IntRecTy::get();
10191037
break;
10201038
case tgtok::XListConcat:
10211039
// We don't know the list type until we parse the first argument
@@ -1061,6 +1079,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
10611079
}
10621080
break;
10631081
case BinOpInit::EQ:
1082+
case BinOpInit::NE:
10641083
if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
10651084
!ArgType->typeIsConvertibleTo(StringRecTy::get())) {
10661085
Error(InitLoc, Twine("expected int, bits, or string; got value of "
@@ -1834,6 +1853,11 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
18341853
case tgtok::XSRL:
18351854
case tgtok::XSHL:
18361855
case tgtok::XEq:
1856+
case tgtok::XNe:
1857+
case tgtok::XLe:
1858+
case tgtok::XLt:
1859+
case tgtok::XGe:
1860+
case tgtok::XGt:
18371861
case tgtok::XListConcat:
18381862
case tgtok::XStrConcat: // Value ::= !binop '(' Value ',' Value ')'
18391863
case tgtok::XIf:

Diff for: ‎llvm/test/TableGen/compare.td

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: llvm-tblgen %s | FileCheck %s
2+
// XFAIL: vg_leak
3+
4+
// CHECK: --- Defs ---
5+
6+
// CHECK: def A0 {
7+
// CHECK: bit eq = 1;
8+
// CHECK: bit ne = 0;
9+
// CHECK: bit le = 1;
10+
// CHECK: bit lt = 0;
11+
// CHECK: bit ge = 1;
12+
// CHECK: bit gt = 0;
13+
// CHECK: }
14+
15+
// CHECK: def A1 {
16+
// CHECK: bit eq = 0;
17+
// CHECK: bit ne = 1;
18+
// CHECK: bit le = 1;
19+
// CHECK: bit lt = 1;
20+
// CHECK: bit ge = 0;
21+
// CHECK: bit gt = 0;
22+
// CHECK: }
23+
24+
// CHECK: def A2 {
25+
// CHECK: bit eq = 0;
26+
// CHECK: bit ne = 1;
27+
// CHECK: bit le = 0;
28+
// CHECK: bit lt = 0;
29+
// CHECK: bit ge = 1;
30+
// CHECK: bit gt = 1;
31+
// CHECK: }
32+
33+
// CHECK: def A3 {
34+
// CHECK: bit eq = 0;
35+
// CHECK: bit ne = 1;
36+
// CHECK: bit le = 0;
37+
// CHECK: bit lt = 0;
38+
// CHECK: bit ge = 1;
39+
// CHECK: bit gt = 1;
40+
// CHECK: }
41+
42+
class A<int x, int y> {
43+
bit eq = !eq(x, y);
44+
bit ne = !ne(x, y);
45+
bit le = !le(x, y);
46+
bit lt = !lt(x, y);
47+
bit ge = !ge(x, y);
48+
bit gt = !gt(x, y);
49+
}
50+
51+
def A0 : A<-3, -3>;
52+
def A1 : A<-1, 4>;
53+
def A2 : A<3, -2>;
54+
def A3 : A<4, 2>;

Diff for: ‎llvm/test/TableGen/eq.td

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
// RUN: llvm-tblgen %s | FileCheck %s
22
// XFAIL: vg_leak
3-
// CHECK: Value = 0
4-
// CHECK: Value = 1
3+
4+
// CHECK-LABEL: def FALSE {
5+
// CHECK: int Value = 0;
6+
// CHECK: }
7+
8+
// CHECK-LABEL: def TRUE {
9+
// CHECK: int Value = 1;
10+
// CHECK: }
11+
12+
// CHECK-LABEL: def X_NE {
13+
// CHECK: bit a = 1;
14+
// CHECK: bit b = 0;
15+
// CHECK: }
516

617
class Base<int V> {
718
int Value = V;
@@ -12,3 +23,8 @@ class Derived<string Truth> :
1223

1324
def TRUE : Derived<"true">;
1425
def FALSE : Derived<"false">;
26+
27+
def X_NE {
28+
bit a = !ne("true", "false");
29+
bit b = !ne("foo", "foo");
30+
}

Diff for: ‎llvm/test/TableGen/eqbit.td

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
// RUN: llvm-tblgen %s | FileCheck %s
22
// XFAIL: vg_leak
3-
// CHECK: a = 6
4-
// CHECK: a = 5
3+
4+
// CHECK-LABEL: def X {
5+
// CHECK: int a = 6;
6+
// CHECK: int c = 5;
7+
// CHECK: }
8+
9+
// CHECK-LABEL: def Y {
10+
// CHECK: int a = 5;
11+
// CHECK: int c = 6;
12+
// CHECK: }
513

614
class A<bit b = 1> {
715
int a = !if(!eq(b, 1), 5, 6);
16+
int c = !if(!ne(b, 1), 5, 6);
817
}
918

1019
def X : A<0>;

0 commit comments

Comments
 (0)
Please sign in to comment.