Skip to content

Commit

Permalink
[clang][Interp] Fix initializing vectors from a list of other vectors
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Apr 30, 2024
1 parent 7faf343 commit 2f9462e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
16 changes: 13 additions & 3 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
18 changes: 18 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/AST/Interp/Opcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions clang/test/AST/Interp/opencl.cl
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)};

0 comments on commit 2f9462e

Please sign in to comment.