[clang] 2f9462e - [clang][Interp] Fix initializing vectors from a list of other vectors

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


Author: Timm Bäder
Date: 2024-04-30T12:41:14+02:00
New Revision: 2f9462e9e4f2b2b493673c39d4ad665175eb0b59

URL: https://github.com/llvm/llvm-project/commit/2f9462e9e4f2b2b493673c39d4ad665175eb0b59
DIFF: https://github.com/llvm/llvm-project/commit/2f9462e9e4f2b2b493673c39d4ad665175eb0b59.diff

LOG: [clang][Interp] Fix initializing vectors from a list of other vectors

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/Opcodes.td
    clang/test/AST/Interp/opencl.cl

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 17f95e7f3cac0d..b07c57ab86d9ad 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1186,11 +1186,21 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
       if (!this->visit(Init))
         return false;
 
-      if (!this->emitInitElem(ElemT, InitIndex, E))
-        return false;
-      ++InitIndex;
+      // If the initializer is of vector type itself, we have to deconstruct
+      // that and initialize all the target fields from the initializer fields.
+      if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
+        if (!this->emitCopyArray(ElemT, 0, InitIndex, InitVecT->getNumElements(), E))
+          return false;
+        InitIndex += InitVecT->getNumElements();
+      } else {
+        if (!this->emitInitElem(ElemT, InitIndex, E))
+          return false;
+        ++InitIndex;
+      }
     }
 
+    assert(InitIndex <= NumVecElements);
+
     // Fill the rest with zeroes.
     for (; InitIndex != NumVecElements; ++InitIndex) {
       if (!this->visitZeroInitializer(ElemT, ElemQT, E))

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 2b650d684be9c4..66d30cc3fbaaba 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2090,6 +2090,24 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
   return true;
 }
 
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+inline bool CopyArray(InterpState &S, CodePtr OpPC, uint32_t SrcIndex, uint32_t DestIndex, uint32_t Size) {
+  const auto &SrcPtr = S.Stk.pop<Pointer>();
+  const auto &DestPtr = S.Stk.peek<Pointer>();
+
+  for (uint32_t I = 0; I != Size; ++I) {
+    const Pointer &SP = SrcPtr.atIndex(SrcIndex + I);
+
+    if (!CheckLoad(S, OpPC, SP))
+      return false;
+
+    const Pointer &DP = DestPtr.atIndex(DestIndex + I);
+    DP.deref<T>() = SP.deref<T>();
+    DP.initialize();
+  }
+  return true;
+}
+
 /// Just takes a pointer and checks if it's an incomplete
 /// array type.
 inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 2a97b978b52325..cfbd7f93c32de8 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -376,7 +376,11 @@ def ArrayElem : Opcode {
   let HasGroup = 1;
 }
 
-
+def CopyArray : Opcode {
+  let Args = [ArgUint32, ArgUint32, ArgUint32];
+  let Types = [AllTypeClass];
+  let HasGroup = 1;
+}
 
 //===----------------------------------------------------------------------===//
 // Direct field accessors

diff  --git a/clang/test/AST/Interp/opencl.cl b/clang/test/AST/Interp/opencl.cl
index e7b9ec5caf2b1e..fd7756fff7c11e 100644
--- a/clang/test/AST/Interp/opencl.cl
+++ b/clang/test/AST/Interp/opencl.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify=ref,both %s
-// RUN: %clang_cc1 -fsyntax-only -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=ref,both %s
+// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=expected,both %s -fexperimental-new-constant-interpreter
 
 // both-no-diagnostics
 
@@ -33,3 +33,6 @@ void foo(int3 arg1, int8 arg2) {
 void negativeShift32(int a,int b) {
   char array0[((int)1)<<40];
 }
+
+int2 A = {1,2};
+int4 B = {(int2)(1,2), (int2)(3,4)};


        


More information about the cfe-commits mailing list