aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorOverMighty <its.overmighty@gmail.com>2024-03-21 16:33:16 +0000
committerGitHub <noreply@github.com>2024-03-21 09:33:16 -0700
commitc1c2551a2876f536b5a06f48fa809aeedbc3d7ba (patch)
tree425b854ed4c1c503ee07d679f418036593d6a6c8 /clang/lib/Sema/SemaChecking.cpp
parent9a87d4d546a4382879b1beb96687acbad0ef4cc0 (diff)
downloadllvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.zip
llvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.tar.gz
llvm-c1c2551a2876f536b5a06f48fa809aeedbc3d7ba.tar.bz2
[clang] Implement __builtin_{clzg,ctzg} (#83431)
Fixes #83075, fixes #83076.
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ef3ab16..246e357 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2399,6 +2399,48 @@ 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.UsualUnaryConversions(TheCall->getArg(1));
+ if (Arg1Res.isInvalid())
+ return true;
+
+ Expr *Arg1 = Arg1Res.get();
+ TheCall->setArg(1, Arg1);
+
+ QualType Arg1Ty = Arg1->getType();
+
+ if (!Arg1Ty->isSpecificBuiltinType(BuiltinType::Int)) {
+ S.Diag(Arg1->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+ << 2 << /*'int' ty*/ 8 << Arg1Ty;
+ return true;
+ }
+ }
+
+ return false;
+}
+
ExprResult
Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
CallExpr *TheCall) {
@@ -3187,6 +3229,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (SemaBuiltinPopcountg(*this, TheCall))
return ExprError();
break;
+ case Builtin::BI__builtin_clzg:
+ case Builtin::BI__builtin_ctzg:
+ if (SemaBuiltinCountZeroBitsGeneric(*this, TheCall))
+ return ExprError();
+ break;
}
if (getLangOpts().HLSL && CheckHLSLBuiltinFunctionCall(BuiltinID, TheCall))