Skip to content

Commit f5a65d8

Browse files
authored
[clang][bytecode] Implement arithmetic, bitwise and compound assignment operator (#108949)
Implement `+`, `-`, `*`, `/` , `%`, `&`, `|`, `^`, `<<`, `>>` and compound assignment operator. --------- Signed-off-by: yronglin <[email protected]>
1 parent 5b4c80f commit f5a65d8

File tree

4 files changed

+614
-28
lines changed

4 files changed

+614
-28
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,12 +1267,8 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
12671267
assert(E->getLHS()->getType()->isVectorType());
12681268
assert(E->getRHS()->getType()->isVectorType());
12691269

1270-
// FIXME: Current only support comparison binary operator, add support for
1271-
// other binary operator.
1272-
if (!E->isComparisonOp() && !E->isLogicalOp())
1273-
return this->emitInvalid(E);
12741270
// Prepare storage for result.
1275-
if (!Initializing) {
1271+
if (!Initializing && !E->isCompoundAssignmentOp()) {
12761272
unsigned LocalIndex = allocateTemporary(E);
12771273
if (!this->emitGetPtrLocal(LocalIndex, E))
12781274
return false;
@@ -1281,6 +1277,9 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
12811277
const Expr *LHS = E->getLHS();
12821278
const Expr *RHS = E->getRHS();
12831279
const auto *VecTy = E->getType()->getAs<VectorType>();
1280+
auto Op = E->isCompoundAssignmentOp()
1281+
? BinaryOperator::getOpForCompoundAssignment(E->getOpcode())
1282+
: E->getOpcode();
12841283

12851284
// The LHS and RHS of a comparison operator must have the same type. So we
12861285
// just use LHS vector element type here.
@@ -1301,6 +1300,17 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13011300
if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
13021301
return false;
13031302

1303+
if (E->isCompoundAssignmentOp() && !this->emitGetLocal(PT_Ptr, LHSOffset, E))
1304+
return false;
1305+
1306+
// BitAdd/BitOr/BitXor/Shl/Shr doesn't support bool type, we need perform the
1307+
// integer promotion.
1308+
bool NeedIntPromot = ElemT == PT_Bool && (E->isBitwiseOp() || E->isShiftOp());
1309+
QualType PromotTy =
1310+
Ctx.getASTContext().getPromotedIntegerType(Ctx.getASTContext().BoolTy);
1311+
PrimType PromotT = classifyPrim(PromotTy);
1312+
PrimType OpT = NeedIntPromot ? PromotT : ElemT;
1313+
13041314
auto getElem = [=](unsigned Offset, unsigned Index) {
13051315
if (!this->emitGetLocal(PT_Ptr, Offset, E))
13061316
return false;
@@ -1311,16 +1321,63 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13111321
return false;
13121322
if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
13131323
return false;
1324+
} else if (NeedIntPromot) {
1325+
if (!this->emitPrimCast(ElemT, PromotT, PromotTy, E))
1326+
return false;
13141327
}
13151328
return true;
13161329
};
13171330

1331+
#define EMIT_ARITH_OP(OP) \
1332+
{ \
1333+
if (ElemT == PT_Float) { \
1334+
if (!this->emit##OP##f(getFPOptions(E), E)) \
1335+
return false; \
1336+
} else { \
1337+
if (!this->emit##OP(ElemT, E)) \
1338+
return false; \
1339+
} \
1340+
break; \
1341+
}
1342+
13181343
for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
13191344
if (!getElem(LHSOffset, I))
13201345
return false;
13211346
if (!getElem(RHSOffset, I))
13221347
return false;
1323-
switch (E->getOpcode()) {
1348+
switch (Op) {
1349+
case BO_Add:
1350+
EMIT_ARITH_OP(Add)
1351+
case BO_Sub:
1352+
EMIT_ARITH_OP(Sub)
1353+
case BO_Mul:
1354+
EMIT_ARITH_OP(Mul)
1355+
case BO_Div:
1356+
EMIT_ARITH_OP(Div)
1357+
case BO_Rem:
1358+
if (!this->emitRem(ElemT, E))
1359+
return false;
1360+
break;
1361+
case BO_And:
1362+
if (!this->emitBitAnd(OpT, E))
1363+
return false;
1364+
break;
1365+
case BO_Or:
1366+
if (!this->emitBitOr(OpT, E))
1367+
return false;
1368+
break;
1369+
case BO_Xor:
1370+
if (!this->emitBitXor(OpT, E))
1371+
return false;
1372+
break;
1373+
case BO_Shl:
1374+
if (!this->emitShl(OpT, ElemT, E))
1375+
return false;
1376+
break;
1377+
case BO_Shr:
1378+
if (!this->emitShr(OpT, ElemT, E))
1379+
return false;
1380+
break;
13241381
case BO_EQ:
13251382
if (!this->emitEQ(ElemT, E))
13261383
return false;
@@ -1356,7 +1413,7 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13561413
return false;
13571414
break;
13581415
default:
1359-
llvm_unreachable("Unsupported binary operator");
1416+
return this->emitInvalid(E);
13601417
}
13611418

13621419
// The result of the comparison is a vector of the same width and number
@@ -1371,10 +1428,19 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13711428
return false;
13721429
}
13731430

1431+
// If we performed an integer promotion, we need to cast the compute result
1432+
// into result vector element type.
1433+
if (NeedIntPromot &&
1434+
!this->emitPrimCast(PromotT, ResultElemT, VecTy->getElementType(), E))
1435+
return false;
1436+
13741437
// Initialize array element with the value we just computed.
13751438
if (!this->emitInitElem(ResultElemT, I, E))
13761439
return false;
13771440
}
1441+
1442+
if (DiscardResult && E->isCompoundAssignmentOp() && !this->emitPopPtr(E))
1443+
return false;
13781444
return true;
13791445
}
13801446

@@ -2294,6 +2360,8 @@ bool Compiler<Emitter>::VisitPointerCompoundAssignOperator(
22942360
template <class Emitter>
22952361
bool Compiler<Emitter>::VisitCompoundAssignOperator(
22962362
const CompoundAssignOperator *E) {
2363+
if (E->getType()->isVectorType())
2364+
return VisitVectorBinOp(E);
22972365

22982366
const Expr *LHS = E->getLHS();
22992367
const Expr *RHS = E->getRHS();

0 commit comments

Comments
 (0)