From: Simon Moll Date: Tue, 8 Jun 2021 11:51:10 +0000 (+0200) Subject: [VP] getDeclarationForParams X-Git-Tag: llvmorg-14-init~4579 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f9d299122f1223e93c54f10401a608f5d481314;p=platform%2Fupstream%2Fllvm.git [VP] getDeclarationForParams `VPIntrinsic::getDeclarationForParams` creates a vp intrinsic declaration for parameters you want to call it with. This is in preparation of a new builder class that makes emitting vp intrinsic code nearly as convenient as using a plain ir builder (aka `VectorBuilder`, to be used by D99750). Reviewed By: frasercrmck, craig.topper, vkmr Differential Revision: https://reviews.llvm.org/D102686 --- diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h index 338103a..606c2b5 100644 --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -389,6 +389,11 @@ public: /// This is the common base class for vector predication intrinsics. class VPIntrinsic : public IntrinsicInst { public: + /// \brief Declares a llvm.vp.* intrinsic in \p M that matches the parameters + /// \p Params. + static Function *getDeclarationForParams(Module *M, Intrinsic::ID, + ArrayRef Params); + static Optional getMaskParamPos(Intrinsic::ID IntrinsicID); static Optional getVectorLengthParamPos(Intrinsic::ID IntrinsicID); diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp index 37ee2f3..30c7ceb 100644 --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -421,6 +421,17 @@ bool VPIntrinsic::canIgnoreVectorLengthParam() const { return false; } +Function *VPIntrinsic::getDeclarationForParams(Module *M, Intrinsic::ID VPID, + ArrayRef Params) { + assert(isVPIntrinsic(VPID) && "not a VP intrinsic"); + + // TODO: Extend this for other VP intrinsics as they are upstreamed. This + // works for binary arithmetic VP intrinsics. + auto *VPFunc = Intrinsic::getDeclaration(M, VPID, Params[0]->getType()); + assert(VPFunc && "Could not declare VP intrinsic"); + return VPFunc; +} + Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const { switch (getIntrinsicID()) { case Intrinsic::uadd_with_overflow: diff --git a/llvm/unittests/IR/VPIntrinsicTest.cpp b/llvm/unittests/IR/VPIntrinsicTest.cpp index ce77fe4..f16e55e 100644 --- a/llvm/unittests/IR/VPIntrinsicTest.cpp +++ b/llvm/unittests/IR/VPIntrinsicTest.cpp @@ -222,4 +222,36 @@ TEST_F(VPIntrinsicTest, IntrinsicIDRoundTrip) { ASSERT_NE(FullTripCounts, 0u); } +/// Check that VPIntrinsic::getDeclarationForParams works. +TEST_F(VPIntrinsicTest, VPIntrinsicDeclarationForParams) { + std::unique_ptr M = CreateVPDeclarationModule(); + assert(M); + + auto OutM = std::make_unique("", M->getContext()); + + for (auto &F : *M) { + auto *FuncTy = F.getFunctionType(); + + // Declare intrinsic anew with explicit types. + std::vector Values; + for (auto *ParamTy : FuncTy->params()) + Values.push_back(UndefValue::get(ParamTy)); + + ASSERT_NE(F.getIntrinsicID(), Intrinsic::not_intrinsic); + auto *NewDecl = VPIntrinsic::getDeclarationForParams( + OutM.get(), F.getIntrinsicID(), Values); + ASSERT_TRUE(NewDecl); + + // Check that 'old decl' == 'new decl'. + ASSERT_EQ(F.getIntrinsicID(), NewDecl->getIntrinsicID()); + auto ItNewParams = NewDecl->getFunctionType()->param_begin(); + auto EndItNewParams = NewDecl->getFunctionType()->param_end(); + for (auto *ParamTy : FuncTy->params()) { + ASSERT_NE(ItNewParams, EndItNewParams); + ASSERT_EQ(*ItNewParams, ParamTy); + ++ItNewParams; + } + } +} + } // end anonymous namespace