[llvm] [TableGen] Short-circuit !cond operator (PR #208942)

Kevin Bravo via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 12 23:38:43 PDT 2026


https://github.com/kbrav updated https://github.com/llvm/llvm-project/pull/208942

>From 305f9ebe1d5761cedb880e8687c9cf0bbfc859be Mon Sep 17 00:00:00 2001
From: kbrav <kbravjr at gmail.com>
Date: Sat, 11 Jul 2026 13:37:00 -0400
Subject: [PATCH 1/3] [TableGen] Short-circuit !cond operator

---
 llvm/lib/TableGen/Record.cpp     | 11 +++++++++++
 llvm/test/TableGen/true-false.td | 13 +++++++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index e9d7febf12272..af076b5ae9475 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2735,6 +2735,17 @@ const Init *CondOpInit::resolveReferences(Resolver &R) const {
     NewConds.push_back(NewCond);
     Changed |= NewCond != Cond;
 
+    // Short-circuit if this cond is true.
+    if (auto *NewCondVal = dyn_cast_or_null<IntInit>(
+            NewCond->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
+      if (NewCondVal->getValue()) {
+        NewVals.push_back(Val->resolveReferences(R));
+        Changed = 1;
+        // Don't push the rest of the conds and values.
+        break;
+      }
+    }
+
     const Init *NewVal = Val->resolveReferences(R);
     NewVals.push_back(NewVal);
     Changed |= NewVal != Val;
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<>;

>From 04ead99412e1e7c27497c8344a310f14866940f7 Mon Sep 17 00:00:00 2001
From: kbrav <kbravjr at gmail.com>
Date: Sat, 11 Jul 2026 15:53:20 -0400
Subject: [PATCH 2/3] Move short-circuit check to after `Val` resolution

---
 llvm/lib/TableGen/Record.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index af076b5ae9475..b35e7be87a7ff 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2735,20 +2735,19 @@ const Init *CondOpInit::resolveReferences(Resolver &R) const {
     NewConds.push_back(NewCond);
     Changed |= NewCond != Cond;
 
+    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()) {
-        NewVals.push_back(Val->resolveReferences(R));
         Changed = 1;
         // Don't push the rest of the conds and values.
         break;
       }
     }
-
-    const Init *NewVal = Val->resolveReferences(R);
-    NewVals.push_back(NewVal);
-    Changed |= NewVal != Val;
   }
 
   if (Changed)

>From e230e9fa5ae62c0f99ae058326316d4eb9910726 Mon Sep 17 00:00:00 2001
From: kbrav <kbravjr at gmail.com>
Date: Mon, 13 Jul 2026 02:38:16 -0400
Subject: [PATCH 3/3] release note

---
 llvm/docs/ReleaseNotes.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 3ca9f5166ad95..38724a2efaeb9 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -185,6 +185,10 @@ Makes programs 10x faster by doing Special New Thing.
 * Outer let statements use ``ID{n-m}`` instead of ``ID<n-m>`` to be consistent
   with inner let statements.
 
+* `!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



More information about the llvm-commits mailing list