================
@@ -12367,8 +12368,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const 
CallExpr *E,
                            BuiltinOp != Builtin::BI__lzcnt &&
                            BuiltinOp != Builtin::BI__lzcnt64;
 
-    if (ZeroIsUndefined && !Val)
-      return Error(E);
+    if (!Val) {
----------------
nickdesaulniers wrote:

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fclzg

> Similar to __builtin_clz, except the argument is type-generic unsigned 
> integer (standard, extended or bit-precise) and there is optional second 
> argument with int type. No integral argument promotions are performed on the 
> first argument. If two arguments are specified, and first argument is 0, the 
> result is the second argument. If only one argument is specified and it is 0, 
> the result is undefined.

The code as written is doing:
1. evaluate arg 0.
2. if evaluation is 0 and the builtin is clzg and num args > 1
3. evaluate arg 1

Consider that it may be cheaper to evaluate the number of args than the full 
subexpression (at least when the sub expression itself is more than just a 
literal iteger).

The code can be rewritten as:

```suggestion
  case Builtin::BI__builtin_clzg:
  case Builtin::BI__builtin_ctzg: {
    unsigned ArgToEval = E->getNumArgs() > 1 ? 1 : 0;
    APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
      return false;
     if (E->getNumArgs() == 1 && !Val)
       return Error(E);
     return Success(...
```

https://github.com/llvm/llvm-project/pull/86577
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to