Skip to content

Commit 425ddc6

Browse files
committed
[TableGen] Make !and short-circuit when either of the operand is zero
By preemptively simplifying the result of `!and`, we can fold some of the conditional operators, like `!if` or `!cond`, as early as possible.
1 parent 6ab26ea commit 425ddc6

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

llvm/lib/TableGen/Record.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,23 @@ const Init *BinOpInit::resolveReferences(Resolver &R) const {
15431543
const Init *lhs = LHS->resolveReferences(R);
15441544
const Init *rhs = RHS->resolveReferences(R);
15451545

1546+
if (getOpcode() == AND) {
1547+
// Short-circuit. Regardless whether this is a logical or bitwise
1548+
// AND.
1549+
if (lhs != LHS)
1550+
if (const auto *LHSi = dyn_cast_or_null<IntInit>(
1551+
lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
1552+
if (!LHSi->getValue())
1553+
return LHSi;
1554+
}
1555+
if (rhs != RHS)
1556+
if (const auto *RHSi = dyn_cast_or_null<IntInit>(
1557+
rhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
1558+
if (!RHSi->getValue())
1559+
return RHSi;
1560+
}
1561+
}
1562+
15461563
if (LHS != lhs || RHS != rhs)
15471564
return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))
15481565
->Fold(R.getCurrentRecord());

llvm/test/TableGen/true-false.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,20 @@ def rec7 {
6767
bits<3> flags = { true, false, true };
6868
}
6969

70+
// The `!and` should be short-circuit such that `!tail` on empty list will never
71+
// be evaluated.
72+
// CHECK: def rec8
73+
// CHECK: list<int> newSeq = [];
74+
// CHECK: list<int> newSeq2 = [];
75+
76+
class Foo <list<int> seq = []> {
77+
bit containsStr = !ne(!find(NAME, "BAR"), -1);
78+
list<int> newSeq = !if(!and(!not(!empty(seq)), containsStr), !tail(seq), seq);
79+
list<int> newSeq2 = !if(!and(containsStr, !not(!empty(seq))), !tail(seq), seq);
80+
}
81+
82+
def rec8 : Foo<>;
83+
7084
#ifdef ERROR1
7185
// ERROR1: Record name '1' is not a string
7286

0 commit comments

Comments
 (0)