[clang] [Clang] Add __builtin_bswapg (PR #162433)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 8 02:12:57 PDT 2025
https://github.com/clingfei updated https://github.com/llvm/llvm-project/pull/162433
>From 92466f3789ce1849ebee8a405efd42e191c591f5 Mon Sep 17 00:00:00 2001
From: clingfei <1599101385 at qq.com>
Date: Wed, 8 Oct 2025 15:05:44 +0800
Subject: [PATCH] [Clang] Add __builtin_bswapg
---
clang/include/clang/Basic/Builtins.td | 6 ++++
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 10 ++++++-
clang/lib/AST/ExprConstant.cpp | 11 ++++++++
clang/lib/CodeGen/CGBuiltin.cpp | 1 +
clang/lib/Sema/SemaChecking.cpp | 28 +++++++++++++++++++
clang/test/AST/ByteCode/builtin-functions.cpp | 4 +++
clang/test/CodeGen/builtins.c | 2 +-
clang/test/Sema/constant-builtins-2.c | 4 +++
clang/test/Sema/constant-builtins.c | 5 +++-
9 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 468121f7d20ab..e65ed2f20be97 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -755,6 +755,12 @@ def BSwap : Builtin, Template<["unsigned short", "uint32_t", "uint64_t"],
let Prototype = "T(T)";
}
+def BSwapg : Builtin {
+ let Spellings = ["__builtin_bswapg"];
+ let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+ let Prototype = "int(...)";
+}
+
def Bitreverse : BitInt8_16_32_64BuiltinsTemplate, Builtin {
let Spellings = ["__builtin_bitreverse"];
let Attributes = [NoThrow, Const, Constexpr];
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 1eea813b8c556..b8d17fbce6d4e 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3288,7 +3288,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case Builtin::BI__builtin_elementwise_ctzg:
return interp__builtin_elementwise_countzeroes(S, OpPC, Frame, Call,
BuiltinID);
-
+ case Builtin::BI__builtin_bswapg: {
+ const APSInt &Val = popToAPSInt(S, Call->getArg(0));
+ assert(Val.getActiveBits() <= 64);
+ if (Val.getBitWidth() == 8)
+ pushInteger(S, Val, Call->getType());
+ else
+ pushInteger(S, Val.byteSwap(), Call->getType());
+ return true;
+ }
case Builtin::BI__builtin_bswap16:
case Builtin::BI__builtin_bswap32:
case Builtin::BI__builtin_bswap64:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 618e1636e9e53..058905e7fd3c0 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13982,6 +13982,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(Val.reverseBits(), E);
}
+ case Builtin::BI__builtin_bswapg: {
+ APSInt Val;
+ if (!EvaluateInteger(E->getArg(0), Val, Info))
+ return false;
+ if (Val.getBitWidth() == 8) {
+ bool ret = Success(Val, E);
+ return ret;
+ }
+
+ return Success(Val.byteSwap(), E);
+ }
case Builtin::BI__builtin_bswap16:
case Builtin::BI__builtin_bswap32:
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 9ee810c9d5775..7733f4dc15f5d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3622,6 +3622,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Builder.CreateArithmeticFence(ArgValue, ConvertType(ArgType)));
return RValue::get(ArgValue);
}
+ case Builtin::BI__builtin_bswapg:
case Builtin::BI__builtin_bswap16:
case Builtin::BI__builtin_bswap32:
case Builtin::BI__builtin_bswap64:
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 063db05665af1..362b53676feaa 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2200,6 +2200,30 @@ static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall,
return false;
}
+/// Checks that __builtin_bswapg was called with a single argument, which is an
+/// unsigned integer, and overrides the return value type to the integer type.
+static bool BuiltinBswapg(Sema &S, CallExpr *TheCall) {
+ if (S.checkArgCount(TheCall, 1))
+ return true;
+ ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));
+ if (ArgRes.isInvalid())
+ return true;
+
+ Expr *Arg = ArgRes.get();
+ TheCall->setArg(0, Arg);
+
+ QualType ArgTy = Arg->getType();
+
+ if (!ArgTy->isIntegerType()) {
+ S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
+ << 1 << /* scalar */ 1 << /* unsigned integer ty */ 1 << /* no fp */ 0
+ << ArgTy;
+ return true;
+ }
+ TheCall->setType(ArgTy);
+ return false;
+}
+
/// Checks that __builtin_popcountg was called with a single argument, which is
/// an unsigned integer.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) {
@@ -3448,6 +3472,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
}
break;
}
+ case Builtin::BI__builtin_bswapg:
+ if (BuiltinBswapg(*this, TheCall))
+ return ExprError();
+ break;
case Builtin::BI__builtin_popcountg:
if (BuiltinPopcountg(*this, TheCall))
return ExprError();
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index f47bc49d9a1a8..84ff9cc137bf3 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -824,6 +824,10 @@ namespace bswap {
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
+ int h6 = __builtin_bswapg(0x12) == 0x12 ? 1 : f();
+ int h7 = __builtin_bswapg(0x1234) == 0x3412 ? 1 : f();
+ int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
+ int h9 = __builtin_bswapg(0x0000000000001234) == 0x3412000000000000 ? 1 : f();
}
#define CFSTR __builtin___CFStringMakeConstantString
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 738814c88bf56..11d8302816c84 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -130,7 +130,7 @@ int main(void) {
P(object_size, (s0, 3));
// Whatever
-
+ P(bswapg, (N));
P(bswap16, (N));
P(bswap32, (N));
P(bswap64, (N));
diff --git a/clang/test/Sema/constant-builtins-2.c b/clang/test/Sema/constant-builtins-2.c
index e465a3c5f0ad8..96bd2c966c2ef 100644
--- a/clang/test/Sema/constant-builtins-2.c
+++ b/clang/test/Sema/constant-builtins-2.c
@@ -479,6 +479,10 @@ int h0 = __builtin_types_compatible_p(int, float);
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
+int h6 = __builtin_bswapg((char)(0x12)) == (char)(0x12) ? 1 : f();
+int h7 = __builtin_bswapg((short)(0x1234)) == (short)(0x3412) ? 1 : f();
+int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
+int h9 = __builtin_bswapg(0x0000000000001234ULL) == 0x3412000000000000 ? 1 : f();
extern long int bi0;
extern __typeof__(__builtin_expect(0, 0)) bi0;
diff --git a/clang/test/Sema/constant-builtins.c b/clang/test/Sema/constant-builtins.c
index 964ab59e787c4..6c13fe96b6b4a 100644
--- a/clang/test/Sema/constant-builtins.c
+++ b/clang/test/Sema/constant-builtins.c
@@ -25,7 +25,10 @@ int h0 = __builtin_types_compatible_p(int,float);
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
-
+int h6 = __builtin_bswapg((char)0x12) == (char)0x12 ? 1 : f();
+int h7 = __builtin_bswapg((short)(0x1234)) == (short)(0x3412) ? 1 : f();
+int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
+int h9 = __builtin_bswapg(0x0000000000001234ULL) == 0x3412000000000000 ? 1 : f();
short somefunc(void);
short t = __builtin_constant_p(5353) ? 42 : somefunc();
More information about the cfe-commits
mailing list