Author: Timm Bäder Date: 2024-04-10T10:45:06+02:00 New Revision: b7a93bc1f230fe01f38f3648437cee74f339c5ac
URL: https://github.com/llvm/llvm-project/commit/b7a93bc1f230fe01f38f3648437cee74f339c5ac DIFF: https://github.com/llvm/llvm-project/commit/b7a93bc1f230fe01f38f3648437cee74f339c5ac.diff LOG: [clang][Interp] Start implementing vector types Map them to primtive arrays, much like complex types. Added: clang/test/AST/Interp/vectors.cpp Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Context.cpp clang/lib/AST/Interp/EvalEmitter.cpp clang/lib/AST/Interp/Pointer.cpp clang/lib/AST/Interp/Program.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a1ce6575148325..acff63cd9dc022 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -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; } diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 15a9d46880e954..274178837bf047 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -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()) { diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp b/clang/lib/AST/Interp/EvalEmitter.cpp index caffb69d83e379..d764b4b6f6d17b 100644 --- a/clang/lib/AST/Interp/EvalEmitter.cpp +++ b/clang/lib/AST/Interp/EvalEmitter.cpp @@ -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()) diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 53998cc3233c94..cddcd6b0151e42 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -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"); }; diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index 25e938e0150322..82367164743fc3 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -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; } diff --git a/clang/test/AST/Interp/vectors.cpp b/clang/test/AST/Interp/vectors.cpp new file mode 100644 index 00000000000000..8afef3c897bff7 --- /dev/null +++ b/clang/test/AST/Interp/vectors.cpp @@ -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); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits