Skip to content

Commit 92466f3

Browse files
committed
[Clang] Add __builtin_bswapg
1 parent 89e2d58 commit 92466f3

File tree

9 files changed

+68
-3
lines changed

9 files changed

+68
-3
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,12 @@ def BSwap : Builtin, Template<["unsigned short", "uint32_t", "uint64_t"],
755755
let Prototype = "T(T)";
756756
}
757757

758+
def BSwapg : Builtin {
759+
let Spellings = ["__builtin_bswapg"];
760+
let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
761+
let Prototype = "int(...)";
762+
}
763+
758764
def Bitreverse : BitInt8_16_32_64BuiltinsTemplate, Builtin {
759765
let Spellings = ["__builtin_bitreverse"];
760766
let Attributes = [NoThrow, Const, Constexpr];

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3288,7 +3288,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32883288
case Builtin::BI__builtin_elementwise_ctzg:
32893289
return interp__builtin_elementwise_countzeroes(S, OpPC, Frame, Call,
32903290
BuiltinID);
3291-
3291+
case Builtin::BI__builtin_bswapg: {
3292+
const APSInt &Val = popToAPSInt(S, Call->getArg(0));
3293+
assert(Val.getActiveBits() <= 64);
3294+
if (Val.getBitWidth() == 8)
3295+
pushInteger(S, Val, Call->getType());
3296+
else
3297+
pushInteger(S, Val.byteSwap(), Call->getType());
3298+
return true;
3299+
}
32923300
case Builtin::BI__builtin_bswap16:
32933301
case Builtin::BI__builtin_bswap32:
32943302
case Builtin::BI__builtin_bswap64:

clang/lib/AST/ExprConstant.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13982,6 +13982,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1398213982

1398313983
return Success(Val.reverseBits(), E);
1398413984
}
13985+
case Builtin::BI__builtin_bswapg: {
13986+
APSInt Val;
13987+
if (!EvaluateInteger(E->getArg(0), Val, Info))
13988+
return false;
13989+
if (Val.getBitWidth() == 8) {
13990+
bool ret = Success(Val, E);
13991+
return ret;
13992+
}
13993+
13994+
return Success(Val.byteSwap(), E);
13995+
}
1398513996

1398613997
case Builtin::BI__builtin_bswap16:
1398713998
case Builtin::BI__builtin_bswap32:

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,6 +3622,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
36223622
Builder.CreateArithmeticFence(ArgValue, ConvertType(ArgType)));
36233623
return RValue::get(ArgValue);
36243624
}
3625+
case Builtin::BI__builtin_bswapg:
36253626
case Builtin::BI__builtin_bswap16:
36263627
case Builtin::BI__builtin_bswap32:
36273628
case Builtin::BI__builtin_bswap64:

clang/lib/Sema/SemaChecking.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,30 @@ static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall,
22002200
return false;
22012201
}
22022202

2203+
/// Checks that __builtin_bswapg was called with a single argument, which is an
2204+
/// unsigned integer, and overrides the return value type to the integer type.
2205+
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall) {
2206+
if (S.checkArgCount(TheCall, 1))
2207+
return true;
2208+
ExprResult ArgRes = S.DefaultLvalueConversion(TheCall->getArg(0));
2209+
if (ArgRes.isInvalid())
2210+
return true;
2211+
2212+
Expr *Arg = ArgRes.get();
2213+
TheCall->setArg(0, Arg);
2214+
2215+
QualType ArgTy = Arg->getType();
2216+
2217+
if (!ArgTy->isIntegerType()) {
2218+
S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2219+
<< 1 << /* scalar */ 1 << /* unsigned integer ty */ 1 << /* no fp */ 0
2220+
<< ArgTy;
2221+
return true;
2222+
}
2223+
TheCall->setType(ArgTy);
2224+
return false;
2225+
}
2226+
22032227
/// Checks that __builtin_popcountg was called with a single argument, which is
22042228
/// an unsigned integer.
22052229
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall) {
@@ -3448,6 +3472,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
34483472
}
34493473
break;
34503474
}
3475+
case Builtin::BI__builtin_bswapg:
3476+
if (BuiltinBswapg(*this, TheCall))
3477+
return ExprError();
3478+
break;
34513479
case Builtin::BI__builtin_popcountg:
34523480
if (BuiltinPopcountg(*this, TheCall))
34533481
return ExprError();

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,10 @@ namespace bswap {
824824
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
825825
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
826826
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
827+
int h6 = __builtin_bswapg(0x12) == 0x12 ? 1 : f();
828+
int h7 = __builtin_bswapg(0x1234) == 0x3412 ? 1 : f();
829+
int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
830+
int h9 = __builtin_bswapg(0x0000000000001234) == 0x3412000000000000 ? 1 : f();
827831
}
828832

829833
#define CFSTR __builtin___CFStringMakeConstantString

clang/test/CodeGen/builtins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ int main(void) {
130130
P(object_size, (s0, 3));
131131

132132
// Whatever
133-
133+
P(bswapg, (N));
134134
P(bswap16, (N));
135135
P(bswap32, (N));
136136
P(bswap64, (N));

clang/test/Sema/constant-builtins-2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ int h0 = __builtin_types_compatible_p(int, float);
479479
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
480480
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
481481
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
482+
int h6 = __builtin_bswapg((char)(0x12)) == (char)(0x12) ? 1 : f();
483+
int h7 = __builtin_bswapg((short)(0x1234)) == (short)(0x3412) ? 1 : f();
484+
int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
485+
int h9 = __builtin_bswapg(0x0000000000001234ULL) == 0x3412000000000000 ? 1 : f();
482486
extern long int bi0;
483487
extern __typeof__(__builtin_expect(0, 0)) bi0;
484488

clang/test/Sema/constant-builtins.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ int h0 = __builtin_types_compatible_p(int,float);
2525
int h3 = __builtin_bswap16(0x1234) == 0x3412 ? 1 : f();
2626
int h4 = __builtin_bswap32(0x1234) == 0x34120000 ? 1 : f();
2727
int h5 = __builtin_bswap64(0x1234) == 0x3412000000000000 ? 1 : f();
28-
28+
int h6 = __builtin_bswapg((char)0x12) == (char)0x12 ? 1 : f();
29+
int h7 = __builtin_bswapg((short)(0x1234)) == (short)(0x3412) ? 1 : f();
30+
int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
31+
int h9 = __builtin_bswapg(0x0000000000001234ULL) == 0x3412000000000000 ? 1 : f();
2932
short somefunc(void);
3033

3134
short t = __builtin_constant_p(5353) ? 42 : somefunc();

0 commit comments

Comments
 (0)