[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 21 04:46:13 PST 2023
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/72984
Tests are from test/Sema/constant-builtins-2.c again.
>From efd400e2f928cfa2bd062c549a02bcbed5c8f95e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 21 Nov 2023 13:44:07 +0100
Subject: [PATCH] [clang][Interp] Implement __builtin_rotate{right,left}
---
clang/lib/AST/Interp/InterpBuiltin.cpp | 49 +++++++++++++++++++++
clang/test/AST/Interp/builtin-functions.cpp | 14 ++++++
2 files changed, 63 insertions(+)
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 9cf206ecc212adb..0f3c073957cd079 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -533,6 +533,29 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
return true;
}
+/// rotateleft(value, amount)
+static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func, const CallExpr *Call,
+ bool Right) {
+ PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+ assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType()));
+
+ APSInt Amount = peekToAPSInt(S.Stk, ArgT);
+ APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2);
+
+ APSInt Result;
+ if (Right)
+ Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())),
+ /*IsUnsigned=*/true);
+ else // Left.
+ Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())),
+ /*IsUnsigned=*/true);
+
+ pushAPSInt(S, Result);
+ return true;
+}
+
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call) {
InterpFrame *Frame = S.Current;
@@ -702,6 +725,32 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;
+ case Builtin::BI__builtin_rotateleft8:
+ case Builtin::BI__builtin_rotateleft16:
+ case Builtin::BI__builtin_rotateleft32:
+ case Builtin::BI__builtin_rotateleft64:
+ case Builtin::BI_rotl8: // Microsoft variants of rotate right
+ case Builtin::BI_rotl16:
+ case Builtin::BI_rotl:
+ case Builtin::BI_lrotl:
+ case Builtin::BI_rotl64:
+ if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false))
+ return false;
+ break;
+
+ case Builtin::BI__builtin_rotateright8:
+ case Builtin::BI__builtin_rotateright16:
+ case Builtin::BI__builtin_rotateright32:
+ case Builtin::BI__builtin_rotateright64:
+ case Builtin::BI_rotr8: // Microsoft variants of rotate right
+ case Builtin::BI_rotr16:
+ case Builtin::BI_rotr:
+ case Builtin::BI_lrotr:
+ case Builtin::BI_rotr64:
+ if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true))
+ return false;
+ break;
+
default:
return false;
}
diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp
index 0726dab37cb4eb0..8fdc6eda5233281 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -331,3 +331,17 @@ namespace bitreverse {
char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1];
char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1];
}
+
+namespace rotateleft {
+ char rotateleft1[__builtin_rotateleft8(0x01, 5) == 0x20 ? 1 : -1];
+ char rotateleft2[__builtin_rotateleft16(0x3210, 11) == 0x8190 ? 1 : -1];
+ char rotateleft3[__builtin_rotateleft32(0x76543210, 22) == 0x841D950C ? 1 : -1];
+ char rotateleft4[__builtin_rotateleft64(0xFEDCBA9876543210ULL, 55) == 0x87F6E5D4C3B2A19ULL ? 1 : -1];
+}
+
+namespace rotateright {
+ char rotateright1[__builtin_rotateright8(0x01, 5) == 0x08 ? 1 : -1];
+ char rotateright2[__builtin_rotateright16(0x3210, 11) == 0x4206 ? 1 : -1];
+ char rotateright3[__builtin_rotateright32(0x76543210, 22) == 0x50C841D9 ? 1 : -1];
+ char rotateright4[__builtin_rotateright64(0xFEDCBA9876543210ULL, 55) == 0xB97530ECA86421FDULL ? 1 : -1];
+}
More information about the cfe-commits
mailing list