Skip to content

Commit

Permalink
[clang][Interp] Start implementing vector types
Browse files Browse the repository at this point in the history
Map them to primtive arrays, much like complex types.
  • Loading branch information
tbaederr committed Apr 10, 2024
1 parent e50c4c8 commit b7a93bc
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 2 deletions.
28 changes: 28 additions & 0 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,34 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
return true;
}

if (const auto *VecT = E->getType()->getAs<VectorType>()) {
unsigned NumVecElements = VecT->getNumElements();
assert(NumVecElements >= E->getNumInits());

QualType ElemQT = VecT->getElementType();
PrimType ElemT = classifyPrim(ElemQT);

// All initializer elements.
unsigned InitIndex = 0;
for (const Expr *Init : E->inits()) {
if (!this->visit(Init))
return false;

if (!this->emitInitElem(ElemT, InitIndex, E))
return false;
++InitIndex;
}

// Fill the rest with zeroes.
for (; InitIndex != NumVecElements; ++InitIndex) {
if (!this->visitZeroInitializer(ElemT, ElemQT, E))
return false;
if (!this->emitInitElem(ElemT, InitIndex, E))
return false;
}
return true;
}

return false;
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ std::optional<PrimType> Context::classify(QualType T) const {
if (T->isBooleanType())
return PT_Bool;

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

if (T->isSignedIntegerOrEnumerationType()) {
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/EvalEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
this->CheckFullyInitialized = CheckFullyInitialized;
this->ConvertResultToRValue =
VD->getAnyInitializer() &&
(VD->getAnyInitializer()->getType()->isAnyComplexType());
(VD->getAnyInitializer()->getType()->isAnyComplexType() ||
VD->getAnyInitializer()->getType()->isVectorType());
EvalResult.setSource(VD);

if (!this->visitDecl(VD) && EvalResult.empty())
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/AST/Interp/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,25 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx) const {
return false;
}

// Vector types.
if (const auto *VT = Ty->getAs<VectorType>()) {
assert(Ptr.getFieldDesc()->isPrimitiveArray());
QualType ElemTy = VT->getElementType();
PrimType ElemT = *Ctx.classify(ElemTy);

SmallVector<APValue> Values;
Values.reserve(VT->getNumElements());
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
TYPE_SWITCH(ElemT, {
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue());
});
}

assert(Values.size() == VT->getNumElements());
R = APValue(Values.data(), Values.size());
return true;
}

llvm_unreachable("invalid value to return");
};

Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/Interp/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,5 +411,12 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
IsMutable);
}

// Same with vector types.
if (const auto *VT = Ty->getAs<VectorType>()) {
PrimType ElemTy = *Ctx.classify(VT->getElementType());
return allocateDescriptor(D, ElemTy, MDSize, VT->getNumElements(), IsConst,
IsTemporary, IsMutable);
}

return nullptr;
}
22 changes: 22 additions & 0 deletions clang/test/AST/Interp/vectors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -verify=ref,both %s

// both-no-diagnostics

typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 A = {1,2,3,4};

/// From constant-expression-cxx11.cpp
namespace Vector {
typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 f(int n) {
return VI4 { n * 3, n + 4, n - 5, n / 6 };
}
constexpr auto v1 = f(10);

typedef double __attribute__((vector_size(32))) VD4;
constexpr VD4 g(int n) {
return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 };
}
constexpr auto v2 = g(4);
}

0 comments on commit b7a93bc

Please sign in to comment.