[clang] b7a93bc - [clang][Interp] Start implementing vector types
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 10 01:45:18 PDT 2024
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);
+}
More information about the cfe-commits
mailing list