Skip to content

Commit cf11eb6

Browse files
authored
[clang][bytecode] Implement logical operators for vector type (#107678)
Implement `&&`, `||` logical operators for vector type. --------- Signed-off-by: yronglin <[email protected]>
1 parent 49e3860 commit cf11eb6

File tree

2 files changed

+110
-2
lines changed

2 files changed

+110
-2
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
12321232

12331233
// FIXME: Current only support comparison binary operator, add support for
12341234
// other binary operator.
1235-
if (!E->isComparisonOp())
1235+
if (!E->isComparisonOp() && !E->isLogicalOp())
12361236
return this->emitInvalid(E);
12371237
// Prepare storage for result.
12381238
if (!Initializing) {
@@ -1267,7 +1267,15 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
12671267
auto getElem = [=](unsigned Offset, unsigned Index) {
12681268
if (!this->emitGetLocal(PT_Ptr, Offset, E))
12691269
return false;
1270-
return this->emitArrayElemPop(ElemT, Index, E);
1270+
if (!this->emitArrayElemPop(ElemT, Index, E))
1271+
return false;
1272+
if (E->isLogicalOp()) {
1273+
if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E))
1274+
return false;
1275+
if (!this->emitPrimCast(PT_Bool, ResultElemT, VecTy->getElementType(), E))
1276+
return false;
1277+
}
1278+
return true;
12711279
};
12721280

12731281
for (unsigned I = 0; I != VecTy->getNumElements(); ++I) {
@@ -1300,6 +1308,16 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
13001308
if (!this->emitGT(ElemT, E))
13011309
return false;
13021310
break;
1311+
case BO_LAnd:
1312+
// a && b is equivalent to a!=0 & b!=0
1313+
if (!this->emitBitAnd(ResultElemT, E))
1314+
return false;
1315+
break;
1316+
case BO_LOr:
1317+
// a || b is equivalent to a!=0 | b!=0
1318+
if (!this->emitBitOr(ResultElemT, E))
1319+
return false;
1320+
break;
13031321
default:
13041322
llvm_unreachable("Unsupported binary operator");
13051323
}

clang/test/AST/ByteCode/constexpr-vectors.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ void CharUsage() {
5757
constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
5858
static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
5959

60+
constexpr auto O = FourCharsVecSize{5, 0, 6, 0} &&
61+
FourCharsVecSize{5, 5, 0, 0};
62+
static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
63+
64+
constexpr auto P = FourCharsVecSize{5, 0, 6, 0} ||
65+
FourCharsVecSize{5, 5, 0, 0};
66+
static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
67+
68+
constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3;
69+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
70+
71+
constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3;
72+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
73+
6074
constexpr auto H1 = FourCharsVecSize{-1, -1, 0, -1};
6175
constexpr auto InvH = -H1;
6276
static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");
@@ -111,6 +125,21 @@ void CharExtVecUsage() {
111125
constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3;
112126
static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
113127

128+
constexpr auto O = FourCharsExtVec{5, 0, 6, 0} &&
129+
FourCharsExtVec{5, 5, 0, 0};
130+
static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
131+
132+
constexpr auto P = FourCharsExtVec{5, 0, 6, 0} ||
133+
FourCharsExtVec{5, 5, 0, 0};
134+
static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
135+
136+
constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3;
137+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
138+
139+
constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3;
140+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
141+
142+
114143
constexpr auto H1 = FourCharsExtVec{-1, -1, 0, -1};
115144
constexpr auto InvH = -H1;
116145
static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");
@@ -165,10 +194,33 @@ void FloatUsage() {
165194
constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
166195
static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
167196

197+
constexpr auto O1 = FourFloatsVecSize{5, 0, 6, 0} &&
198+
FourFloatsVecSize{5, 5, 0, 0};
199+
static_assert(O1[0] == 1 && O1[1] == 0 && O1[2] == 0 && O1[3] == 0, "");
200+
201+
constexpr auto P1 = FourFloatsVecSize{5, 0, 6, 0} ||
202+
FourFloatsVecSize{5, 5, 0, 0};
203+
static_assert(P1[0] == 1 && P1[1] == 1 && P1[2] == 1 && P1[3] == 0, "");
204+
205+
constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
206+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
207+
208+
constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
209+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
210+
211+
168212
constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00};
169213
constexpr auto Z = -Y;
170214
static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");
171215

216+
constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
217+
FourFloatsVecSize{5, 5, 0, 0};
218+
static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
219+
220+
constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
221+
FourFloatsVecSize{5, 5, 0, 0};
222+
static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
223+
172224
// Operator ~ is illegal on floats.
173225
constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}}
174226

@@ -219,6 +271,20 @@ void FloatVecUsage() {
219271
constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
220272
static_assert(H[0] == -1 && H[1] == -1 && H[2] == 0 && H[3] == -1, "");
221273

274+
constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
275+
FourFloatsVecSize{5, 5, 0, 0};
276+
static_assert(O[0] == 1 && O[1] == 0 && O[2] == 0 && O[3] == 0, "");
277+
278+
constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} ||
279+
FourFloatsVecSize{5, 5, 0, 0};
280+
static_assert(P[0] == 1 && P[1] == 1 && P[2] == 1 && P[3] == 0, "");
281+
282+
constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3;
283+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
284+
285+
constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3;
286+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
287+
222288
constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00};
223289
constexpr auto Z = -Y;
224290
static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");
@@ -234,6 +300,18 @@ void I128Usage() {
234300
constexpr auto a = FourI128VecSize{1, 2, 3, 4};
235301
static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, "");
236302

303+
constexpr auto a1 = FourI128VecSize{5, 0, 6, 0} && FourI128VecSize{5, 5, 0, 0};
304+
static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, "");
305+
306+
constexpr auto a2 = FourI128VecSize{5, 0, 6, 0} || FourI128VecSize{5, 5, 0, 0};
307+
static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, "");
308+
309+
constexpr auto Q = FourI128VecSize{5, 0, 6, 0} && 3;
310+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
311+
312+
constexpr auto R = FourI128VecSize{5, 0, 6, 0} || 3;
313+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
314+
237315
constexpr auto b = a < 3;
238316
static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, "");
239317

@@ -249,6 +327,18 @@ void I128VecUsage() {
249327
constexpr auto a = FourI128ExtVec{1, 2, 3, 4};
250328
static_assert(a[0] == 1 && a[1] == 2 && a[2] == 3 && a[3] == 4, "");
251329

330+
constexpr auto a1 = FourI128ExtVec{5, 0, 6, 0} && FourI128ExtVec{5, 5, 0, 0};
331+
static_assert(a1[0] == 1 && a1[1] == 0 && a1[2] == 0 && a1[3] == 0, "");
332+
333+
constexpr auto a2 = FourI128ExtVec{5, 0, 6, 0} || FourI128ExtVec{5, 5, 0, 0};
334+
static_assert(a2[0] == 1 && a2[1] == 1 && a2[2] == 1 && a2[3] == 0, "");
335+
336+
constexpr auto Q = FourI128ExtVec{5, 0, 6, 0} && 3;
337+
static_assert(Q[0] == 1 && Q[1] == 0 && Q[2] == 1 && Q[3] == 0, "");
338+
339+
constexpr auto R = FourI128ExtVec{5, 0, 6, 0} || 3;
340+
static_assert(R[0] == 1 && R[1] == 1 && R[2] == 1 && R[3] == 1, "");
341+
252342
constexpr auto b = a < 3;
253343
static_assert(b[0] == -1 && b[1] == -1 && b[2] == 0 && b[3] == 0, "");
254344

0 commit comments

Comments
 (0)