================ @@ -5312,6 +5314,120 @@ bool Compiler<Emitter>::VisitComplexUnaryOperator(const UnaryOperator *E) { return true; } +template <class Emitter> +bool Compiler<Emitter>::VisitVectorUnaryOperator(const UnaryOperator *E) { + const Expr *SubExpr = E->getSubExpr(); + assert(SubExpr->getType()->isVectorType()); + + if (DiscardResult) + return this->discard(SubExpr); + + auto prepareResult = [=]() -> bool { + if (!Initializing) { + std::optional<unsigned> LocalIndex = allocateLocal(SubExpr); + if (!LocalIndex) + return false; + return this->emitGetPtrLocal(*LocalIndex, E); + } + return true; + }; + + // The offset of the temporary, if we created one. + unsigned SubExprOffset = ~0u; + auto createTemp = [=, &SubExprOffset]() -> bool { + SubExprOffset = this->allocateLocalPrimitive(SubExpr, PT_Ptr, true, false); + if (!this->visit(SubExpr)) + return false; + return this->emitSetLocal(PT_Ptr, SubExprOffset, E); + }; + + const auto *VecTy = SubExpr->getType()->getAs<VectorType>(); + PrimType ElemT = classifyVectorElementType(SubExpr->getType()); + auto getElem = [=](unsigned Offset, unsigned Index) -> bool { + if (!this->emitGetLocal(PT_Ptr, Offset, E)) + return false; + return this->emitArrayElemPop(ElemT, Index, E); + }; + + switch (E->getOpcode()) { + case UO_Plus: // +x + return this->delegate(SubExpr); + case UO_Minus: + if (!prepareResult()) + return false; + if (!createTemp()) + return false; + for (unsigned I = 0; I != VecTy->getNumElements(); ++I) { + if (!getElem(SubExprOffset, I)) + return false; + if (!this->emitNeg(ElemT, E)) + return false; + if (!this->emitInitElem(ElemT, I, E)) + return false; + } + break; + case UO_LNot: { // !x + if (!prepareResult()) + return false; + if (!createTemp()) + return false; + + // In C++, the logic operators !, &&, || are available for vectors. !v is + // equivalent to v == 0. + // + // The result of the comparison is a vector of the same width and number of + // elements as the comparison operands with a signed integral element type. + // + // https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + QualType SignedVecTy = E->getType(); + PrimType SignedElemT = + classifyPrim(SignedVecTy->getAs<VectorType>()->getElementType()); + for (unsigned I = 0; I != VecTy->getNumElements(); ++I) { + if (!getElem(SubExprOffset, I)) + return false; + // operator ! on vectors returns -1 for 'truth', so negate it. + if (!this->emitPrimCast(ElemT, PT_Bool, Ctx.getASTContext().BoolTy, E)) + return false; ---------------- tbaederr wrote:
I think this can just be a `emitCast(ElemT, PT_Bool, E)` https://github.com/llvm/llvm-project/pull/105996 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits