[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