@@ -2931,6 +2931,11 @@ handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
2931
2931
break;
2932
2932
}
2933
2933
2934
+ // The boolean operations on these vector types use an instruction that
2935
+ // results in a mask of '-1' for the 'truth' value. Ensure that we negate 1
2936
+ // to -1 to make sure that we produce the correct value.
2937
+ Result.negate();
2938
+
2934
2939
return true;
2935
2940
}
2936
2941
@@ -10179,7 +10184,8 @@ namespace {
10179
10184
bool VisitInitListExpr(const InitListExpr *E);
10180
10185
bool VisitUnaryImag(const UnaryOperator *E);
10181
10186
bool VisitBinaryOperator(const BinaryOperator *E);
10182
- // FIXME: Missing: unary -, unary ~, conditional operator (for GNU
10187
+ bool VisitUnaryOperator(const UnaryOperator *E);
10188
+ // FIXME: Missing: conditional operator (for GNU
10183
10189
// conditional select), shufflevector, ExtVectorElementExpr
10184
10190
};
10185
10191
} // end anonymous namespace
@@ -10364,6 +10370,83 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
10364
10370
return Success(LHSValue, E);
10365
10371
}
10366
10372
10373
+ static llvm::Optional<APValue> handleVectorUnaryOperator(ASTContext &Ctx,
10374
+ QualType ResultTy,
10375
+ UnaryOperatorKind Op,
10376
+ APValue Elt) {
10377
+ switch (Op) {
10378
+ case UO_Plus:
10379
+ // Nothing to do here.
10380
+ return Elt;
10381
+ case UO_Minus:
10382
+ if (Elt.getKind() == APValue::Int) {
10383
+ Elt.getInt().negate();
10384
+ } else {
10385
+ assert(Elt.getKind() == APValue::Float &&
10386
+ "Vector can only be int or float type");
10387
+ Elt.getFloat().changeSign();
10388
+ }
10389
+ return Elt;
10390
+ case UO_Not:
10391
+ // This is only valid for integral types anyway, so we don't have to handle
10392
+ // float here.
10393
+ assert(Elt.getKind() == APValue::Int &&
10394
+ "Vector operator ~ can only be int");
10395
+ Elt.getInt().flipAllBits();
10396
+ return Elt;
10397
+ case UO_LNot: {
10398
+ if (Elt.getKind() == APValue::Int) {
10399
+ Elt.getInt() = !Elt.getInt();
10400
+ // operator ! on vectors returns -1 for 'truth', so negate it.
10401
+ Elt.getInt().negate();
10402
+ return Elt;
10403
+ }
10404
+ assert(Elt.getKind() == APValue::Float &&
10405
+ "Vector can only be int or float type");
10406
+ // Float types result in an int of the same size, but -1 for true, or 0 for
10407
+ // false.
10408
+ APSInt EltResult{Ctx.getIntWidth(ResultTy),
10409
+ ResultTy->isUnsignedIntegerType()};
10410
+ if (Elt.getFloat().isZero())
10411
+ EltResult.setAllBits();
10412
+ else
10413
+ EltResult.clearAllBits();
10414
+
10415
+ return APValue{EltResult};
10416
+ }
10417
+ default:
10418
+ // FIXME: Implement the rest of the unary operators.
10419
+ return llvm::None;
10420
+ }
10421
+ }
10422
+
10423
+ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
10424
+ Expr *SubExpr = E->getSubExpr();
10425
+ const auto *VD = SubExpr->getType()->castAs<VectorType>();
10426
+ // This result element type differs in the case of negating a floating point
10427
+ // vector, since the result type is the a vector of the equivilant sized
10428
+ // integer.
10429
+ const QualType ResultEltTy = VD->getElementType();
10430
+ UnaryOperatorKind Op = E->getOpcode();
10431
+
10432
+ APValue SubExprValue;
10433
+ if (!Evaluate(SubExprValue, Info, SubExpr))
10434
+ return false;
10435
+
10436
+ assert(SubExprValue.getVectorLength() == VD->getNumElements() &&
10437
+ "Vector length doesn't match type?");
10438
+
10439
+ SmallVector<APValue, 4> ResultElements;
10440
+ for (unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
10441
+ llvm::Optional<APValue> Elt = handleVectorUnaryOperator(
10442
+ Info.Ctx, ResultEltTy, Op, SubExprValue.getVectorElt(EltNum));
10443
+ if (!Elt)
10444
+ return false;
10445
+ ResultElements.push_back(*Elt);
10446
+ }
10447
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
10448
+ }
10449
+
10367
10450
//===----------------------------------------------------------------------===//
10368
10451
// Array Evaluation
10369
10452
//===----------------------------------------------------------------------===//
0 commit comments