Skip to content

Commit 89c79ee

Browse files
committed
[Clang] support vector subscript expressions in constant evaluator
1 parent 64e6388 commit 89c79ee

File tree

3 files changed

+668
-151
lines changed

3 files changed

+668
-151
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ namespace {
221221
ArraySize = 2;
222222
MostDerivedLength = I + 1;
223223
IsArray = true;
224+
} else if (Type->isVectorType()) {
225+
const VectorType *CT = Type->castAs<VectorType>();
226+
Type = CT->getElementType();
227+
ArraySize = CT->getNumElements();
228+
MostDerivedLength = I + 1;
229+
IsArray = true;
224230
} else if (const FieldDecl *FD = getAsField(Path[I])) {
225231
Type = FD->getType();
226232
ArraySize = 0;
@@ -437,6 +443,15 @@ namespace {
437443
MostDerivedArraySize = 2;
438444
MostDerivedPathLength = Entries.size();
439445
}
446+
/// Update this designator to refer to the given vector component.
447+
void addVectorUnchecked(const VectorType *VecTy) {
448+
Entries.push_back(PathEntry::ArrayIndex(0));
449+
450+
MostDerivedType = VecTy->getElementType();
451+
MostDerivedIsArrayElement = true;
452+
MostDerivedArraySize = VecTy->getNumElements();
453+
MostDerivedPathLength = Entries.size();
454+
}
440455
void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
441456
void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
442457
const APSInt &N);
@@ -1732,6 +1747,10 @@ namespace {
17321747
if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
17331748
Designator.addComplexUnchecked(EltTy, Imag);
17341749
}
1750+
void addVector(EvalInfo &Info, const Expr *E, const VectorType *VecTy) {
1751+
if (checkSubobject(Info, E, CSK_ArrayIndex))
1752+
Designator.addVectorUnchecked(VecTy);
1753+
}
17351754
void clearIsNullPointer() {
17361755
IsNullPtr = false;
17371756
}
@@ -1890,6 +1909,8 @@ static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
18901909
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
18911910
EvalInfo &Info);
18921911

1912+
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info);
1913+
18931914
//===----------------------------------------------------------------------===//
18941915
// Misc utilities
18951916
//===----------------------------------------------------------------------===//
@@ -3278,6 +3299,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
32783299
return true;
32793300
}
32803301

3302+
static bool HandeLValueVectorComponent(EvalInfo &Info, const Expr *E,
3303+
LValue &LVal, const VectorType *VecTy,
3304+
APSInt &Adjustment) {
3305+
LVal.addVector(Info, E, VecTy);
3306+
3307+
CharUnits SizeOfComponent;
3308+
if (!HandleSizeof(Info, E->getExprLoc(), VecTy->getElementType(),
3309+
SizeOfComponent))
3310+
return false;
3311+
LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfComponent);
3312+
return true;
3313+
}
3314+
32813315
/// Try to evaluate the initializer for a variable declaration.
32823316
///
32833317
/// \param Info Information about the ongoing evaluation.
@@ -3718,7 +3752,8 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
37183752
}
37193753

37203754
// If this is our last pass, check that the final object type is OK.
3721-
if (I == N || (I == N - 1 && ObjType->isAnyComplexType())) {
3755+
if (I == N || (I == N - 1 &&
3756+
(ObjType->isAnyComplexType() || ObjType->isVectorType()))) {
37223757
// Accesses to volatile objects are prohibited.
37233758
if (ObjType.isVolatileQualified() && isFormalAccess(handler.AccessKind)) {
37243759
if (Info.getLangOpts().CPlusPlus) {
@@ -3823,6 +3858,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
38233858
return handler.found(Index ? O->getComplexFloatImag()
38243859
: O->getComplexFloatReal(), ObjType);
38253860
}
3861+
} else if (ObjType->isVectorType()) {
3862+
// Next Subobject is a vector element
3863+
uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3864+
O = &O->getVectorElt(Index);
38263865
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
38273866
if (Field->isMutable() &&
38283867
!Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8756,14 +8795,28 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
87568795
}
87578796

87588797
bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
8759-
// FIXME: Deal with vectors as array subscript bases.
8760-
if (E->getBase()->getType()->isVectorType() ||
8761-
E->getBase()->getType()->isSveVLSBuiltinType())
8798+
8799+
if (E->getBase()->getType()->isSveVLSBuiltinType())
87628800
return Error(E);
87638801

87648802
APSInt Index;
87658803
bool Success = true;
87668804

8805+
if (E->getBase()->getType()->isVectorType()) {
8806+
for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
8807+
Success = (SubExpr == E->getBase())
8808+
? EvaluateLValue(SubExpr, Result, Info, true)
8809+
: EvaluateInteger(SubExpr, Index, Info);
8810+
}
8811+
if (Success) {
8812+
Success = HandeLValueVectorComponent(
8813+
Info, E, Result, E->getBase()->getType()->castAs<VectorType>(),
8814+
Index);
8815+
return Success;
8816+
}
8817+
return false;
8818+
}
8819+
87678820
// C++17's rules require us to evaluate the LHS first, regardless of which
87688821
// side is the base.
87698822
for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {

clang/test/CodeGenCXX/temporaries.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -673,16 +673,12 @@ namespace Vector {
673673
vi4a v;
674674
vi4b w;
675675
};
676-
// CHECK: alloca
677-
// CHECK: extractelement
678-
// CHECK: store i32 {{.*}}, ptr @_ZGRN6Vector1rE_
679-
// CHECK: store ptr @_ZGRN6Vector1rE_, ptr @_ZN6Vector1rE,
676+
// @_ZGRN6Vector1rE_ = internal global i32 0, align 4
677+
// @_ZN6Vector1rE = constant ptr @_ZGRN6Vector1rE_, align 8
680678
int &&r = S().v[1];
681679

682-
// CHECK: alloca
683-
// CHECK: extractelement
684-
// CHECK: store i32 {{.*}}, ptr @_ZGRN6Vector1sE_
685-
// CHECK: store ptr @_ZGRN6Vector1sE_, ptr @_ZN6Vector1sE,
680+
// @_ZGRN6Vector1sE_ = internal global i32 0, align 4
681+
// @_ZN6Vector1sE = constant ptr @_ZGRN6Vector1sE_, align 8
686682
int &&s = S().w[1];
687683
// FIXME PR16204: The following code leads to an assertion in Sema.
688684
//int &&s = S().w.y;

0 commit comments

Comments
 (0)