@@ -2931,6 +2931,11 @@ handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
29312931 break;
29322932 }
29332933
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+
29342939 return true;
29352940}
29362941
@@ -10179,7 +10184,8 @@ namespace {
1017910184 bool VisitInitListExpr(const InitListExpr *E);
1018010185 bool VisitUnaryImag(const UnaryOperator *E);
1018110186 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
1018310189 // conditional select), shufflevector, ExtVectorElementExpr
1018410190 };
1018510191} // end anonymous namespace
@@ -10364,6 +10370,83 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1036410370 return Success(LHSValue, E);
1036510371}
1036610372
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+
1036710450//===----------------------------------------------------------------------===//
1036810451// Array Evaluation
1036910452//===----------------------------------------------------------------------===//
0 commit comments