[clang] 74e65ee - [clang][Interp] Handle Shifts in OpenCL correctly

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 30 01:03:08 PDT 2024


Author: Timm Bäder
Date: 2024-04-30T10:02:50+02:00
New Revision: 74e65eec48ee87c34e06a09ad25a1029506dd60d

URL: https://github.com/llvm/llvm-project/commit/74e65eec48ee87c34e06a09ad25a1029506dd60d
DIFF: https://github.com/llvm/llvm-project/commit/74e65eec48ee87c34e06a09ad25a1029506dd60d.diff

LOG: [clang][Interp] Handle Shifts in OpenCL correctly

We need to adjust the RHS to account for the LHS bitwidth.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h
    clang/test/AST/Interp/opencl.cl

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9da0286deada17..2b650d684be9c4 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1935,10 +1935,15 @@ template <PrimType NameL, PrimType NameR>
 inline bool Shr(InterpState &S, CodePtr OpPC) {
   using LT = typename PrimConv<NameL>::T;
   using RT = typename PrimConv<NameR>::T;
-  const auto &RHS = S.Stk.pop<RT>();
+  auto RHS = S.Stk.pop<RT>();
   const auto &LHS = S.Stk.pop<LT>();
   const unsigned Bits = LHS.bitWidth();
 
+  // OpenCL 6.3j: shift values are effectively % word size of LHS.
+  if (S.getLangOpts().OpenCL)
+    RT::bitAnd(RHS, RT::from(LHS.bitWidth() - 1, RHS.bitWidth()),
+               RHS.bitWidth(), &RHS);
+
   if (!CheckShift(S, OpPC, LHS, RHS, Bits))
     return false;
 
@@ -1960,10 +1965,15 @@ template <PrimType NameL, PrimType NameR>
 inline bool Shl(InterpState &S, CodePtr OpPC) {
   using LT = typename PrimConv<NameL>::T;
   using RT = typename PrimConv<NameR>::T;
-  const auto &RHS = S.Stk.pop<RT>();
+  auto RHS = S.Stk.pop<RT>();
   const auto &LHS = S.Stk.pop<LT>();
   const unsigned Bits = LHS.bitWidth();
 
+  // OpenCL 6.3j: shift values are effectively % word size of LHS.
+  if (S.getLangOpts().OpenCL)
+    RT::bitAnd(RHS, RT::from(LHS.bitWidth() - 1, RHS.bitWidth()),
+               RHS.bitWidth(), &RHS);
+
   if (!CheckShift(S, OpPC, LHS, RHS, Bits))
     return false;
 

diff  --git a/clang/test/AST/Interp/opencl.cl b/clang/test/AST/Interp/opencl.cl
index b9ba4f8b9b555a..e7b9ec5caf2b1e 100644
--- a/clang/test/AST/Interp/opencl.cl
+++ b/clang/test/AST/Interp/opencl.cl
@@ -30,3 +30,6 @@ void foo(int3 arg1, int8 arg2) {
   int res12[vec_step(void) == 1 ? 1 : -1];
 }
 
+void negativeShift32(int a,int b) {
+  char array0[((int)1)<<40];
+}


        


More information about the cfe-commits mailing list