[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72984 >From 1a2bda9e9b28a4f99e723bf6265cb769e048a315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= 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 4384ace6b6be5e..deba38e4e9ddc0 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -579,6 +579,29 @@ static bool interp__builtin_expect(InterpState , CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState , 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 , CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -754,6 +777,32 @@ bool InterpretBuiltin(InterpState , 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 left + 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 35a1f9a75092a0..62fe9b081c78fa 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -339,3 +339,17 @@ namespace expect { static_assert(__builtin_expect(a(),1) == 12, ""); static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, ""); } + +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]; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72984 >From d728e5a0a38ee24040b360c3aa53ba9575d5c897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= 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 | 15 +++ 2 files changed, 64 insertions(+) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 4384ace6b6be5e..deba38e4e9ddc0 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -579,6 +579,29 @@ static bool interp__builtin_expect(InterpState , CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState , 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 , CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -754,6 +777,32 @@ bool InterpretBuiltin(InterpState , 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 left + 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 35a1f9a75092a0..0e50bfe5d6e30e 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -332,10 +332,25 @@ namespace bitreverse { char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1]; } +<<< HEAD namespace expect { constexpr int a() { return 12; } static_assert(__builtin_expect(a(),1) == 12, ""); static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, ""); +=== +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]; +>>> 6417ae298a1a ([clang][Interp] Implement __builtin_rotate{right,left}) } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
@@ -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]; AaronBallman wrote: Ah, I was going off our public documentation which does not suggest that the value to be rotated is unsigned! Carry on. https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72984 >From 71ee39aaf9e962701168290394333654a22ed918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= 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 | 15 +++ 2 files changed, 64 insertions(+) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 4384ace6b6be5e..deba38e4e9ddc0 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -579,6 +579,29 @@ static bool interp__builtin_expect(InterpState , CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState , 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 , CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -754,6 +777,32 @@ bool InterpretBuiltin(InterpState , 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 left + 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 35a1f9a75092a0..0e50bfe5d6e30e 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -332,10 +332,25 @@ namespace bitreverse { char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1]; } +<<< HEAD namespace expect { constexpr int a() { return 12; } static_assert(__builtin_expect(a(),1) == 12, ""); static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, ""); +=== +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]; +>>> 6417ae298a1a ([clang][Interp] Implement __builtin_rotate{right,left}) } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
@@ -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]; tbaederr wrote: They builtin functions are defined as having unsigned parameters, so does a test like that make sense? https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
@@ -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]; AaronBallman wrote: It would be good to have some tests involving a signed operand being rotated. (I verified that there's no UB when shifting a 1 bit into or out of the most significant bit.) https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/AaronBallman edited https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/AaronBallman approved this pull request. LGTM aside from a testing request https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) Changes Tests are from test/Sema/constant-builtins-2.c again. --- Full diff: https://github.com/llvm/llvm-project/pull/72984.diff 2 Files Affected: - (modified) clang/lib/AST/Interp/InterpBuiltin.cpp (+49) - (modified) clang/test/AST/Interp/builtin-functions.cpp (+14) ``diff 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 , CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState , 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 , CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -702,6 +725,32 @@ bool InterpretBuiltin(InterpState , 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]; +} `` https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
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?= 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 , CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState , 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 , CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -702,6 +725,32 @@ bool InterpretBuiltin(InterpState , 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]; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits