[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)

2023-12-12 Thread Timm Baeder via cfe-commits

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)

2023-12-11 Thread Timm Baeder via cfe-commits

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)

2023-12-11 Thread Timm Baeder via cfe-commits

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)

2023-12-08 Thread Aaron Ballman via cfe-commits


@@ -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)

2023-12-08 Thread Timm Baeder via cfe-commits

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)

2023-12-08 Thread Timm Baeder via cfe-commits


@@ -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)

2023-12-06 Thread Aaron Ballman via cfe-commits


@@ -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)

2023-12-06 Thread Aaron Ballman via cfe-commits

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)

2023-12-06 Thread Aaron Ballman via cfe-commits

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)

2023-11-27 Thread Timm Baeder via cfe-commits

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)

2023-11-21 Thread via cfe-commits

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)

2023-11-21 Thread Timm Baeder via cfe-commits

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