Skip to content

Commit 8e95454

Browse files
committed
[clang][Interp] Support ExtVectorElementExprs
1 parent 3e8f217 commit 8e95454

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,6 +2735,65 @@ bool ByteCodeExprGen<Emitter>::VisitShuffleVectorExpr(
27352735
return true;
27362736
}
27372737

2738+
template <class Emitter>
2739+
bool ByteCodeExprGen<Emitter>::VisitExtVectorElementExpr(
2740+
const ExtVectorElementExpr *E) {
2741+
const Expr *Base = E->getBase();
2742+
2743+
SmallVector<uint32_t, 4> Indices;
2744+
E->getEncodedElementAccess(Indices);
2745+
2746+
if (Indices.size() == 1) {
2747+
if (!this->visit(Base))
2748+
return false;
2749+
2750+
if (E->isGLValue()) {
2751+
if (!this->emitConstUint32(Indices[0], E))
2752+
return false;
2753+
return this->emitArrayElemPtrPop(PT_Uint32, E);
2754+
}
2755+
// Else, also load the value.
2756+
return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
2757+
}
2758+
2759+
// Create a local variable for the base.
2760+
unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,
2761+
/*IsExtended=*/false);
2762+
if (!this->visit(Base))
2763+
return false;
2764+
if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
2765+
return false;
2766+
2767+
// Now the vector variable for the return value.
2768+
if (!Initializing) {
2769+
std::optional<unsigned> ResultIndex;
2770+
ResultIndex = allocateLocal(E);
2771+
if (!ResultIndex)
2772+
return false;
2773+
if (!this->emitGetPtrLocal(*ResultIndex, E))
2774+
return false;
2775+
}
2776+
2777+
assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
2778+
2779+
PrimType ElemT =
2780+
classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
2781+
uint32_t DstIndex = 0;
2782+
for (uint32_t I : Indices) {
2783+
if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
2784+
return false;
2785+
if (!this->emitArrayElemPop(ElemT, I, E))
2786+
return false;
2787+
if (!this->emitInitElem(ElemT, DstIndex, E))
2788+
return false;
2789+
++DstIndex;
2790+
}
2791+
2792+
// Leave the result pointer on the stack.
2793+
assert(!DiscardResult);
2794+
return true;
2795+
}
2796+
27382797
template <class Emitter>
27392798
bool ByteCodeExprGen<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
27402799
if (!E->isExpressibleAsConstantInitializer())

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
128128
bool VisitAddrLabelExpr(const AddrLabelExpr *E);
129129
bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
130130
bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
131+
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
131132
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
132133

133134
protected:

clang/test/AST/Interp/vectors.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,14 @@ namespace BoolToSignedIntegralCast{
7070
static_assert(intsT[2] == -1, "");// ref-error {{not an integral constant expression}}
7171
static_assert(intsT[3] == -1, "");// ref-error {{not an integral constant expression}}
7272
}
73+
74+
namespace VectorElementExpr {
75+
typedef int int2 __attribute__((ext_vector_type(2)));
76+
typedef int int4 __attribute__((ext_vector_type(4)));
77+
constexpr int oneElt = int4(3).x;
78+
static_assert(oneElt == 3);
79+
80+
constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
81+
static_assert(twoElts.x == 22, ""); // ref-error {{not an integral constant expression}}
82+
static_assert(twoElts.y == 33, ""); // ref-error {{not an integral constant expression}}
83+
}

clang/test/CodeGenOpenCLCXX/constexpr.clcpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s
2+
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s
23

34
typedef int int2 __attribute__((ext_vector_type(2)));
45
typedef int int4 __attribute__((ext_vector_type(4)));

0 commit comments

Comments
 (0)