Skip to content

Commit b7a93bc

Browse files
committed
[clang][Interp] Start implementing vector types
Map them to primtive arrays, much like complex types.
1 parent e50c4c8 commit b7a93bc

File tree

6 files changed

+80
-2
lines changed

6 files changed

+80
-2
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,34 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
10331033
return true;
10341034
}
10351035

1036+
if (const auto *VecT = E->getType()->getAs<VectorType>()) {
1037+
unsigned NumVecElements = VecT->getNumElements();
1038+
assert(NumVecElements >= E->getNumInits());
1039+
1040+
QualType ElemQT = VecT->getElementType();
1041+
PrimType ElemT = classifyPrim(ElemQT);
1042+
1043+
// All initializer elements.
1044+
unsigned InitIndex = 0;
1045+
for (const Expr *Init : E->inits()) {
1046+
if (!this->visit(Init))
1047+
return false;
1048+
1049+
if (!this->emitInitElem(ElemT, InitIndex, E))
1050+
return false;
1051+
++InitIndex;
1052+
}
1053+
1054+
// Fill the rest with zeroes.
1055+
for (; InitIndex != NumVecElements; ++InitIndex) {
1056+
if (!this->visitZeroInitializer(ElemT, ElemQT, E))
1057+
return false;
1058+
if (!this->emitInitElem(ElemT, InitIndex, E))
1059+
return false;
1060+
}
1061+
return true;
1062+
}
1063+
10361064
return false;
10371065
}
10381066

clang/lib/AST/Interp/Context.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ std::optional<PrimType> Context::classify(QualType T) const {
120120
if (T->isBooleanType())
121121
return PT_Bool;
122122

123-
if (T->isAnyComplexType())
123+
// We map these to primitive arrays.
124+
if (T->isAnyComplexType() || T->isVectorType())
124125
return std::nullopt;
125126

126127
if (T->isSignedIntegerOrEnumerationType()) {

clang/lib/AST/Interp/EvalEmitter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
5151
this->CheckFullyInitialized = CheckFullyInitialized;
5252
this->ConvertResultToRValue =
5353
VD->getAnyInitializer() &&
54-
(VD->getAnyInitializer()->getType()->isAnyComplexType());
54+
(VD->getAnyInitializer()->getType()->isAnyComplexType() ||
55+
VD->getAnyInitializer()->getType()->isVectorType());
5556
EvalResult.setSource(VD);
5657

5758
if (!this->visitDecl(VD) && EvalResult.empty())

clang/lib/AST/Interp/Pointer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,25 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx) const {
342342
return false;
343343
}
344344

345+
// Vector types.
346+
if (const auto *VT = Ty->getAs<VectorType>()) {
347+
assert(Ptr.getFieldDesc()->isPrimitiveArray());
348+
QualType ElemTy = VT->getElementType();
349+
PrimType ElemT = *Ctx.classify(ElemTy);
350+
351+
SmallVector<APValue> Values;
352+
Values.reserve(VT->getNumElements());
353+
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
354+
TYPE_SWITCH(ElemT, {
355+
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue());
356+
});
357+
}
358+
359+
assert(Values.size() == VT->getNumElements());
360+
R = APValue(Values.data(), Values.size());
361+
return true;
362+
}
363+
345364
llvm_unreachable("invalid value to return");
346365
};
347366

clang/lib/AST/Interp/Program.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,5 +411,12 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
411411
IsMutable);
412412
}
413413

414+
// Same with vector types.
415+
if (const auto *VT = Ty->getAs<VectorType>()) {
416+
PrimType ElemTy = *Ctx.classify(VT->getElementType());
417+
return allocateDescriptor(D, ElemTy, MDSize, VT->getNumElements(), IsConst,
418+
IsTemporary, IsMutable);
419+
}
420+
414421
return nullptr;
415422
}

clang/test/AST/Interp/vectors.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2+
// RUN: %clang_cc1 -verify=ref,both %s
3+
4+
// both-no-diagnostics
5+
6+
typedef int __attribute__((vector_size(16))) VI4;
7+
constexpr VI4 A = {1,2,3,4};
8+
9+
/// From constant-expression-cxx11.cpp
10+
namespace Vector {
11+
typedef int __attribute__((vector_size(16))) VI4;
12+
constexpr VI4 f(int n) {
13+
return VI4 { n * 3, n + 4, n - 5, n / 6 };
14+
}
15+
constexpr auto v1 = f(10);
16+
17+
typedef double __attribute__((vector_size(32))) VD4;
18+
constexpr VD4 g(int n) {
19+
return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 };
20+
}
21+
constexpr auto v2 = g(4);
22+
}

0 commit comments

Comments
 (0)