[clang] [clang] Implement __builtin_{clzg,ctzg} (PR #83431)

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 29 14:55:57 PST 2024


================
@@ -2212,6 +2212,54 @@ static bool SemaBuiltinPopcountg(Sema &S, CallExpr *TheCall) {
   return false;
 }
 
+/// Checks that __builtin_{clzg,ctzg} was called with a first argument, which is
+/// an unsigned integer, and an optional second argument, which is promoted to
+/// an 'int'.
+static bool SemaBuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {
+  if (checkArgCountRange(S, TheCall, 1, 2))
+    return true;
+
+  ExprResult Arg0Res = S.DefaultLvalueConversion(TheCall->getArg(0));
+  if (Arg0Res.isInvalid())
+    return true;
+
+  Expr *Arg0 = Arg0Res.get();
+  TheCall->setArg(0, Arg0);
+
+  QualType Arg0Ty = Arg0->getType();
+
+  if (!Arg0Ty->isUnsignedIntegerType()) {
+    S.Diag(Arg0->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+        << 1 << /*unsigned integer ty*/ 7 << Arg0Ty;
+    return true;
+  }
+
+  if (TheCall->getNumArgs() > 1) {
+    ExprResult Arg1Res = S.DefaultLvalueConversion(TheCall->getArg(1));
+    if (Arg1Res.isInvalid())
+      return true;
+
+    Expr *Arg1 = Arg1Res.get();
+    TheCall->setArg(1, Arg1);
+
+    QualType Arg1Ty = Arg1->getType();
+
+    if (S.Context.isPromotableIntegerType(Arg1Ty)) {
----------------
efriedma-quic wrote:

This isn't quite the same as the way promotion normally works for arguments; it forbids some conversions we would normally do.  Maybe that's fine?  Maybe worth stating a bit more explicitly in the documentation.

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


More information about the cfe-commits mailing list