[llvm] [TableGen] Make `!and` and `!or` short-circuit (PR #113963)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 10:25:56 PST 2024


================
@@ -1543,6 +1543,29 @@ const Init *BinOpInit::resolveReferences(Resolver &R) const {
   const Init *lhs = LHS->resolveReferences(R);
   const Init *rhs = RHS->resolveReferences(R);
 
+  unsigned Opc = getOpcode();
+  if (Opc == AND || Opc == OR) {
+    // Short-circuit. Regardless whether this is a logical or bitwise
+    // AND/OR.
+    // Ideally we could also short-circuit `!or(true, ...)`, but it's
+    // difficult to do it right without knowing if rest of the operands
+    // are all `bit` or not. Therefore, we're only implementing a relatively
+    // limited version of short-circuit against all ones (`true` is casted
+    // to 1 rather than all ones before we evaluate `!or`).
+    if (const auto *LHSi = dyn_cast_or_null<IntInit>(
+            lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
+      if ((Opc == AND && !LHSi->getValue()) ||
+          (Opc == OR && LHSi->getValue() == -1))
+        return LHSi;
+    }
+    if (const auto *RHSi = dyn_cast_or_null<IntInit>(
----------------
jurahul wrote:

Or is this still under the umbrella that these evaluations do not produce side effects? I'd think even then, there may be value in just sticking with well known rules. I am assuming this is also sufficient for the cases you'd like to handle.

https://github.com/llvm/llvm-project/pull/113963


More information about the llvm-commits mailing list