Skip to content

Commit 2f9462e

Browse files
committed
[clang][Interp] Fix initializing vectors from a list of other vectors
1 parent 7faf343 commit 2f9462e

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,11 +1186,21 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
11861186
if (!this->visit(Init))
11871187
return false;
11881188

1189-
if (!this->emitInitElem(ElemT, InitIndex, E))
1190-
return false;
1191-
++InitIndex;
1189+
// If the initializer is of vector type itself, we have to deconstruct
1190+
// that and initialize all the target fields from the initializer fields.
1191+
if (const auto *InitVecT = Init->getType()->getAs<VectorType>()) {
1192+
if (!this->emitCopyArray(ElemT, 0, InitIndex, InitVecT->getNumElements(), E))
1193+
return false;
1194+
InitIndex += InitVecT->getNumElements();
1195+
} else {
1196+
if (!this->emitInitElem(ElemT, InitIndex, E))
1197+
return false;
1198+
++InitIndex;
1199+
}
11921200
}
11931201

1202+
assert(InitIndex <= NumVecElements);
1203+
11941204
// Fill the rest with zeroes.
11951205
for (; InitIndex != NumVecElements; ++InitIndex) {
11961206
if (!this->visitZeroInitializer(ElemT, ElemQT, E))

clang/lib/AST/Interp/Interp.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,24 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
20902090
return true;
20912091
}
20922092

2093+
template <PrimType Name, class T = typename PrimConv<Name>::T>
2094+
inline bool CopyArray(InterpState &S, CodePtr OpPC, uint32_t SrcIndex, uint32_t DestIndex, uint32_t Size) {
2095+
const auto &SrcPtr = S.Stk.pop<Pointer>();
2096+
const auto &DestPtr = S.Stk.peek<Pointer>();
2097+
2098+
for (uint32_t I = 0; I != Size; ++I) {
2099+
const Pointer &SP = SrcPtr.atIndex(SrcIndex + I);
2100+
2101+
if (!CheckLoad(S, OpPC, SP))
2102+
return false;
2103+
2104+
const Pointer &DP = DestPtr.atIndex(DestIndex + I);
2105+
DP.deref<T>() = SP.deref<T>();
2106+
DP.initialize();
2107+
}
2108+
return true;
2109+
}
2110+
20932111
/// Just takes a pointer and checks if it's an incomplete
20942112
/// array type.
20952113
inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {

clang/lib/AST/Interp/Opcodes.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,11 @@ def ArrayElem : Opcode {
376376
let HasGroup = 1;
377377
}
378378

379-
379+
def CopyArray : Opcode {
380+
let Args = [ArgUint32, ArgUint32, ArgUint32];
381+
let Types = [AllTypeClass];
382+
let HasGroup = 1;
383+
}
380384

381385
//===----------------------------------------------------------------------===//
382386
// Direct field accessors

clang/test/AST/Interp/opencl.cl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify=ref,both %s
2-
// RUN: %clang_cc1 -fsyntax-only -verify=expected,both %s -fexperimental-new-constant-interpreter
1+
// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=ref,both %s
2+
// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=expected,both %s -fexperimental-new-constant-interpreter
33

44
// both-no-diagnostics
55

@@ -33,3 +33,6 @@ void foo(int3 arg1, int8 arg2) {
3333
void negativeShift32(int a,int b) {
3434
char array0[((int)1)<<40];
3535
}
36+
37+
int2 A = {1,2};
38+
int4 B = {(int2)(1,2), (int2)(3,4)};

0 commit comments

Comments
 (0)