[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:22:58 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:
In C/C++, the short-circuit is only applied to the LHS of the operator. That is, if the RHS happens to be 0 for an &&, the LHS is still evaluated. This seems to diverge from that, in the sense if RHS is 0, the LHS won't be evaluated. Is that the intent? Or should we abide by C/C++ style short-circuit to reduce the element of surprise?
https://github.com/llvm/llvm-project/pull/113963
More information about the llvm-commits
mailing list