[clang] [clang][x86][bytecode] Replace interp__builtin_rotate with static bool interp__builtin_elementwise_int_binop callback #160289 (PR #161924)

via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 5 17:30:54 PDT 2025


https://github.com/rdez13 updated https://github.com/llvm/llvm-project/pull/161924

>From 6a347f60d6c467ec1a6fd2dd6122bcf710741939 Mon Sep 17 00:00:00 2001
From: rdez13 <ryandezfuli at yahoo.com>
Date: Fri, 3 Oct 2025 18:28:08 -0400
Subject: [PATCH 1/4] llvm#160289 added new rotate right and left helper
 functions and changed return for BuiltinID  switch case rotl64 and rotr64 to
 use elementwise binary op instead of builtin rotate

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 6053237b1a261..dc09dc33f29c3 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -56,6 +56,20 @@ static APSInt popToAPSInt(InterpState &S, QualType T) {
   return popToAPSInt(S.Stk, *S.getContext().classify(T));
 }
 
+static APInt ROTL_fn(const APSInt &A, const APSInt &B) {
+  const APInt &X = static_cast<const APInt &>(A);
+  const unsigned BW = X.getBitWidth();
+  const uint64_t Amt = B.getZExtValue();
+  return X.rotl(static_cast<unsigned>(Amt % BW));
+}
+
+static APInt ROTR_fn(const APSInt &A, const APSInt &B) {
+  const APInt &X = static_cast<const APInt &>(A);
+  const unsigned BW = X.getBitWidth();
+  const uint64_t Amt = B.getZExtValue();
+  return X.rotr(static_cast<unsigned>(Amt % BW));
+}
+
 /// Pushes \p Val on the stack as the type given by \p QT.
 static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
   assert(QT->isSignedIntegerOrEnumerationType() ||
@@ -3162,7 +3176,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotl:
   case Builtin::BI_lrotl:
   case Builtin::BI_rotl64:
-    return interp__builtin_rotate(S, OpPC, Frame, Call, /*Right=*/false);
+    return interp__builtin_elementwise_int_binop(S, OpPC, Call, ROTL_fn);
 
   case Builtin::BI__builtin_rotateright8:
   case Builtin::BI__builtin_rotateright16:
@@ -3173,7 +3187,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotr:
   case Builtin::BI_lrotr:
   case Builtin::BI_rotr64:
-    return interp__builtin_rotate(S, OpPC, Frame, Call, /*Right=*/true);
+    return interp__builtin_elementwise_int_binop(S, OpPC, Call, ROTR_fn);
 
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:

>From ffb2a3fc16508611671a084b34cc59fe0f1f0ada Mon Sep 17 00:00:00 2001
From: rdez13 <ryandezfuli at yahoo.com>
Date: Sat, 4 Oct 2025 11:42:52 -0400
Subject: [PATCH 2/4] llvm#160289 removed helper functions and used non
 capturing lambdas instead, removed non explicit casts

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index dc09dc33f29c3..b354b84560740 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -56,20 +56,6 @@ static APSInt popToAPSInt(InterpState &S, QualType T) {
   return popToAPSInt(S.Stk, *S.getContext().classify(T));
 }
 
-static APInt ROTL_fn(const APSInt &A, const APSInt &B) {
-  const APInt &X = static_cast<const APInt &>(A);
-  const unsigned BW = X.getBitWidth();
-  const uint64_t Amt = B.getZExtValue();
-  return X.rotl(static_cast<unsigned>(Amt % BW));
-}
-
-static APInt ROTR_fn(const APSInt &A, const APSInt &B) {
-  const APInt &X = static_cast<const APInt &>(A);
-  const unsigned BW = X.getBitWidth();
-  const uint64_t Amt = B.getZExtValue();
-  return X.rotr(static_cast<unsigned>(Amt % BW));
-}
-
 /// Pushes \p Val on the stack as the type given by \p QT.
 static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) {
   assert(QT->isSignedIntegerOrEnumerationType() ||
@@ -3176,7 +3162,10 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotl:
   case Builtin::BI_lrotl:
   case Builtin::BI_rotl64:
-    return interp__builtin_elementwise_int_binop(S, OpPC, Call, ROTL_fn);
+    return interp__builtin_elementwise_int_binop(
+        S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
+          return A.rotl((unsigned)B.getLimitedValue());
+        });
 
   case Builtin::BI__builtin_rotateright8:
   case Builtin::BI__builtin_rotateright16:
@@ -3187,7 +3176,10 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotr:
   case Builtin::BI_lrotr:
   case Builtin::BI_rotr64:
-    return interp__builtin_elementwise_int_binop(S, OpPC, Call, ROTR_fn);
+    return interp__builtin_elementwise_int_binop(
+        S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
+          return A.rotr((unsigned)B.getLimitedValue());
+        });
 
   case Builtin::BI__builtin_ffs:
   case Builtin::BI__builtin_ffsl:

>From 1132144de691039e5d9497d93d269ae8c9cbfca9 Mon Sep 17 00:00:00 2001
From: rdez13 <ryandezfuli at yahoo.com>
Date: Sat, 4 Oct 2025 14:25:13 -0400
Subject: [PATCH 3/4] llvm#160289 computed amount as B.urem(A.getBitWidth()) to
 match previouse behavior, and removed interp__builtin_rotate which is now
 unused

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 23 ++---------------------
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index b354b84560740..ed1f6b77d07e0 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -736,25 +736,6 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
   return true;
 }
 
-/// rotateleft(value, amount)
-static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
-                                   const InterpFrame *Frame,
-                                   const CallExpr *Call, bool Right) {
-  APSInt Amount = popToAPSInt(S, Call->getArg(1));
-  APSInt Value = popToAPSInt(S, Call->getArg(0));
-
-  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);
-
-  pushInteger(S, Result, Call->getType());
-  return true;
-}
-
 static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC,
                                 const InterpFrame *Frame,
                                 const CallExpr *Call) {
@@ -3164,7 +3145,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotl64:
     return interp__builtin_elementwise_int_binop(
         S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
-          return A.rotl((unsigned)B.getLimitedValue());
+          return A.rotl(B.urem(A.getBitWidth()));
         });
 
   case Builtin::BI__builtin_rotateright8:
@@ -3178,7 +3159,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_rotr64:
     return interp__builtin_elementwise_int_binop(
         S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
-          return A.rotr((unsigned)B.getLimitedValue());
+          return A.rotr(B.urem(A.getBitWidth()));
         });
 
   case Builtin::BI__builtin_ffs:

>From 1e18ebebf0f5025bbe72bce42b02ae04cd936131 Mon Sep 17 00:00:00 2001
From: rdez13 <ryandezfuli at yahoo.com>
Date: Sun, 5 Oct 2025 20:30:40 -0400
Subject: [PATCH 4/4] llvm#160289 replaced A and B with Value and Amount,
 removed the explicit urem and called Value.rotl/r(Amount) directly

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index ed1f6b77d07e0..3e6c0e8925c0d 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -3144,8 +3144,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_lrotl:
   case Builtin::BI_rotl64:
     return interp__builtin_elementwise_int_binop(
-        S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
-          return A.rotl(B.urem(A.getBitWidth()));
+        S, OpPC, Call, [](const APSInt &Value, const APSInt &Amount) -> APInt {
+          return Value.rotl(Amount);
         });
 
   case Builtin::BI__builtin_rotateright8:
@@ -3158,8 +3158,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
   case Builtin::BI_lrotr:
   case Builtin::BI_rotr64:
     return interp__builtin_elementwise_int_binop(
-        S, OpPC, Call, [](const APSInt &A, const APSInt &B) -> APInt {
-          return A.rotr(B.urem(A.getBitWidth()));
+        S, OpPC, Call, [](const APSInt &Value, const APSInt &Amount) -> APInt {
+          return Value.rotr(Amount);
         });
 
   case Builtin::BI__builtin_ffs:



More information about the cfe-commits mailing list