[llvm] 7cfe30d - [TableGen] Short-circuit !cond operator (#208942)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 13:51:34 PDT 2026
Author: Kevin Bravo
Date: 2026-07-16T13:51:29-07:00
New Revision: 7cfe30df768f109dbaead1ed5f7538c10ba65d2e
URL: https://github.com/llvm/llvm-project/commit/7cfe30df768f109dbaead1ed5f7538c10ba65d2e
DIFF: https://github.com/llvm/llvm-project/commit/7cfe30df768f109dbaead1ed5f7538c10ba65d2e.diff
LOG: [TableGen] Short-circuit !cond operator (#208942)
Fixes #163213
TableGen `!cond` operator currently resolves all subsequent conditions
and values even if it already found a condition that resolves to `true`.
This change short-circuits on the first `true` resolution found
iterating from left to right. It folds a new `CondOpInit` with only the
conditions and values that have already been resolved, including the
current condition and value.
Added:
Modified:
llvm/docs/ReleaseNotes.md
llvm/docs/TableGen/ProgRef.rst
llvm/lib/TableGen/Record.cpp
llvm/test/TableGen/true-false.td
Removed:
################################################################################
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index af037473e3653..e12dd0d7a8b71 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -60,6 +60,10 @@ Makes programs 10x faster by doing Special New Thing.
### Changes to TableGen
+* `!cond` operator short-circuits at the first `true` condition. Subsequent
+ `condition : value` pairs, along with their corresponding side effects,
+ are left unresolved.
+
### Changes to Interprocedural Optimizations
### Changes to Vectorizers
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 95a2b38dbf59a..d9f12208fc5de 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -1746,6 +1746,10 @@ and non-0 as true.
If false, the operator tests *cond2* and returns *val2* if the result is
true. And so forth. An error is reported if no conditions are true.
+ !cond short-circuits at the first true condition, resolving to that
+ condition's corresponding value. Subsequent conditions and values are left
+ unresolved.
+
This example produces the sign word for an integer::
!cond(!lt(x, 0) : "negative", !eq(x, 0) : "zero", true : "positive")
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index e9d7febf12272..ac62e2f5785ae 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2738,6 +2738,16 @@ const Init *CondOpInit::resolveReferences(Resolver &R) const {
const Init *NewVal = Val->resolveReferences(R);
NewVals.push_back(NewVal);
Changed |= NewVal != Val;
+
+ // Short-circuit if this cond is true.
+ if (auto *NewCondVal = dyn_cast_or_null<IntInit>(
+ NewCond->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
+ if (NewCondVal->getValue()) {
+ Changed = true;
+ // Don't push the rest of the conds and values.
+ break;
+ }
+ }
}
if (Changed)
diff --git a/llvm/test/TableGen/true-false.td b/llvm/test/TableGen/true-false.td
index 5fa5702314489..f4110fab5054b 100644
--- a/llvm/test/TableGen/true-false.td
+++ b/llvm/test/TableGen/true-false.td
@@ -67,13 +67,15 @@ def rec7 {
bits<3> flags = { true, false, true };
}
-// `!and` and `!or` should be short-circuited such that any of the `!head` or
-// `!tail` on empty list below will never be evaluated.
+// `!and`, `!or`, and '!cond' should be short-circuited such that any of the
+// `!head` or `!tail` on empty list below will never be evaluated.
// CHECK: def rec8
// CHECK: bit v = 0;
// CHECK: int v2 = -1;
// CHECK: list<int> newSeq = [];
// CHECK: list<int> newSeq2 = [];
+// CHECK: C = 0;
+// CHECK: D = 1;
class Foo <list<int> seq = []> {
bit v = !and(false, !head(seq));
@@ -82,6 +84,13 @@ class Foo <list<int> seq = []> {
bit unresolved = !ne(!find(NAME, "BAR"), -1);
list<int> newSeq = !if(!and(false, unresolved), !tail(seq), seq);
list<int> newSeq2 = !if(!or(-1, unresolved), seq, !tail(seq));
+
+ int C = !cond(!eq(!size(seq), 0): 0,
+ !eq(!size(!tail(seq)), 1) : 1,
+ !eq(!size(!tail(seq)), 2): 2);
+ int D = !cond(!eq(!size(seq), 1): 0,
+ !eq(!size(seq), 0): 1,
+ !eq(!size(!tail(seq)), 2): 2);
}
def rec8 : Foo<>;
More information about the llvm-commits
mailing list