[clang] 8e95454 - [clang][Interp] Support ExtVectorElementExprs
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 15 06:12:54 PDT 2024
Author: Timm Bäder
Date: 2024-06-15T15:12:36+02:00
New Revision: 8e954541581270c497cc961b08eff69dc41bc18d
URL: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d
DIFF: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d.diff
LOG: [clang][Interp] Support ExtVectorElementExprs
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/vectors.cpp
clang/test/CodeGenOpenCLCXX/constexpr.clcpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 13a68f3d05f6a..e61c0a70a0d8a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2735,6 +2735,65 @@ bool ByteCodeExprGen<Emitter>::VisitShuffleVectorExpr(
return true;
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitExtVectorElementExpr(
+ const ExtVectorElementExpr *E) {
+ const Expr *Base = E->getBase();
+
+ SmallVector<uint32_t, 4> Indices;
+ E->getEncodedElementAccess(Indices);
+
+ if (Indices.size() == 1) {
+ if (!this->visit(Base))
+ return false;
+
+ if (E->isGLValue()) {
+ if (!this->emitConstUint32(Indices[0], E))
+ return false;
+ return this->emitArrayElemPtrPop(PT_Uint32, E);
+ }
+ // Else, also load the value.
+ return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
+ }
+
+ // Create a local variable for the base.
+ unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,
+ /*IsExtended=*/false);
+ if (!this->visit(Base))
+ return false;
+ if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
+ return false;
+
+ // Now the vector variable for the return value.
+ if (!Initializing) {
+ std::optional<unsigned> ResultIndex;
+ ResultIndex = allocateLocal(E);
+ if (!ResultIndex)
+ return false;
+ if (!this->emitGetPtrLocal(*ResultIndex, E))
+ return false;
+ }
+
+ assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
+
+ PrimType ElemT =
+ classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
+ uint32_t DstIndex = 0;
+ for (uint32_t I : Indices) {
+ if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
+ return false;
+ if (!this->emitArrayElemPop(ElemT, I, E))
+ return false;
+ if (!this->emitInitElem(ElemT, DstIndex, E))
+ return false;
+ ++DstIndex;
+ }
+
+ // Leave the result pointer on the stack.
+ assert(!DiscardResult);
+ return true;
+}
+
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
if (!E->isExpressibleAsConstantInitializer())
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 7bb5304cac71e..b0faac8020fb2 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,6 +128,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool VisitAddrLabelExpr(const AddrLabelExpr *E);
bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
+ bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
protected:
diff --git a/clang/test/AST/Interp/vectors.cpp b/clang/test/AST/Interp/vectors.cpp
index 1e0d473cbca5a..61c400b57b3f8 100644
--- a/clang/test/AST/Interp/vectors.cpp
+++ b/clang/test/AST/Interp/vectors.cpp
@@ -70,3 +70,14 @@ namespace BoolToSignedIntegralCast{
static_assert(intsT[2] == -1, "");// ref-error {{not an integral constant expression}}
static_assert(intsT[3] == -1, "");// ref-error {{not an integral constant expression}}
}
+
+namespace VectorElementExpr {
+ typedef int int2 __attribute__((ext_vector_type(2)));
+ typedef int int4 __attribute__((ext_vector_type(4)));
+ constexpr int oneElt = int4(3).x;
+ static_assert(oneElt == 3);
+
+ constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
+ static_assert(twoElts.x == 22, ""); // ref-error {{not an integral constant expression}}
+ static_assert(twoElts.y == 33, ""); // ref-error {{not an integral constant expression}}
+}
diff --git a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
index 0576418c944ba..5de7106fe5417 100644
--- a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
+++ b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s
typedef int int2 __attribute__((ext_vector_type(2)));
typedef int int4 __attribute__((ext_vector_type(4)));
More information about the cfe-commits
mailing list