Skip to content

Commit d5c5ed3

Browse files
authored
[clang][bytecode] Handle vector assignments (#155573)
1 parent 57a4727 commit d5c5ed3

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13831383
assert(E->getRHS()->getType()->isVectorType());
13841384

13851385
// Prepare storage for result.
1386-
if (!Initializing && !E->isCompoundAssignmentOp()) {
1386+
if (!Initializing && !E->isCompoundAssignmentOp() && !E->isAssignmentOp()) {
13871387
UnsignedOrNone LocalIndex = allocateTemporary(E);
13881388
if (!LocalIndex)
13891389
return false;
@@ -1402,6 +1402,21 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
14021402
PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
14031403
PrimType ResultElemT = this->classifyVectorElementType(E->getType());
14041404

1405+
if (E->getOpcode() == BO_Assign) {
1406+
assert(Ctx.getASTContext().hasSameUnqualifiedType(
1407+
LHS->getType()->castAs<VectorType>()->getElementType(),
1408+
RHS->getType()->castAs<VectorType>()->getElementType()));
1409+
if (!this->visit(LHS))
1410+
return false;
1411+
if (!this->visit(RHS))
1412+
return false;
1413+
if (!this->emitCopyArray(ElemT, 0, 0, VecTy->getNumElements(), E))
1414+
return false;
1415+
if (DiscardResult)
1416+
return this->emitPopPtr(E);
1417+
return true;
1418+
}
1419+
14051420
// Evaluate LHS and save value to LHSOffset.
14061421
unsigned LHSOffset =
14071422
this->allocateLocalPrimitive(LHS, PT_Ptr, /*IsConst=*/true);

clang/test/AST/ByteCode/vectors.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,28 @@ namespace {
143143
constexpr __m128d v_mm_cvtps_pd = _mm_cvtps_pd(kf1);
144144
static_assert(v_mm_cvtps_pd[0] == -1.0 && v_mm_cvtps_pd[1] == +2.0);
145145
}
146+
147+
namespace Assign {
148+
constexpr int a2() {
149+
VI a = {0, 0, 0, 0};
150+
VI b; // both-warning {{C++20 extension}}
151+
152+
b = {1,1,1,1};
153+
return b[0] + b[1] + b[2] + b[3];
154+
}
155+
156+
static_assert(a2() == 4);
157+
158+
typedef short v2int16_t __attribute__((ext_vector_type(2)));
159+
typedef unsigned short v2int_t __attribute__((ext_vector_type(2)));
160+
161+
162+
constexpr bool invalid() {
163+
v2int16_t a = {0, 0};
164+
v2int_t b; // both-warning {{C++20 extension}}
165+
b = a; // both-error {{incompatible type}}
166+
167+
return true;
168+
}
169+
static_assert(invalid()); // both-error {{not an integral constant expression}}
170+
}

0 commit comments

Comments
 (0)