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))); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits