diff --git a/llvm/include/llvm/IR/VectorBuilder.h b/llvm/include/llvm/IR/VectorBuilder.h deleted file mode 100644 index bc23842d8e6bd..0000000000000 --- a/llvm/include/llvm/IR/VectorBuilder.h +++ /dev/null @@ -1,120 +0,0 @@ -//===- llvm/VectorBuilder.h - Builder for VP Intrinsics ---------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the VectorBuilder class, which is used as a convenient way -// to create VP intrinsics as if they were LLVM instructions with a consistent -// and simplified interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_IR_VECTORBUILDER_H -#define LLVM_IR_VECTORBUILDER_H - -#include "llvm/Support/Compiler.h" -#include -#include -#include -#include - -namespace llvm { - -class VectorBuilder { -public: - enum class Behavior { - // Abort if the requested VP intrinsic could not be created. - // This is useful for strict consistency. - ReportAndAbort = 0, - - // Return a default-initialized value if the requested VP intrinsic could - // not be created. - // This is useful for a defensive fallback to non-VP code. - SilentlyReturnNone = 1, - }; - -private: - IRBuilderBase &Builder; - Behavior ErrorHandling; - - // Explicit mask parameter. - Value *Mask; - // Explicit vector length parameter. - Value *ExplicitVectorLength; - // Compile-time vector length. - ElementCount StaticVectorLength; - - // Get mask/evl value handles for the current configuration. - Value &requestMask(); - Value &requestEVL(); - - LLVM_ABI void handleError(const char *ErrorMsg) const; - template - RetType returnWithError(const char *ErrorMsg) const { - handleError(ErrorMsg); - return RetType(); - } - - /// Helper function for creating VP intrinsic call. - Value *createVectorInstructionImpl(Intrinsic::ID VPID, Type *ReturnTy, - ArrayRef VecOpArray, - const Twine &Name = Twine()); - -public: - VectorBuilder(IRBuilderBase &Builder, - Behavior ErrorHandling = Behavior::ReportAndAbort) - : Builder(Builder), ErrorHandling(ErrorHandling), Mask(nullptr), - ExplicitVectorLength(nullptr), - StaticVectorLength(ElementCount::getFixed(0)) {} - - LLVM_ABI Module &getModule() const; - LLVMContext &getContext() const { return Builder.getContext(); } - - // All-true mask for the currently configured explicit vector length. - LLVM_ABI Value *getAllTrueMask(); - - VectorBuilder &setMask(Value *NewMask) { - Mask = NewMask; - return *this; - } - VectorBuilder &setEVL(Value *NewExplicitVectorLength) { - ExplicitVectorLength = NewExplicitVectorLength; - return *this; - } - VectorBuilder &setStaticVL(unsigned NewFixedVL) { - StaticVectorLength = ElementCount::getFixed(NewFixedVL); - return *this; - } - - /// Get the flags to be applied to created floating point ops. - const FastMathFlags &getFastMathFlags() const { - return Builder.getFastMathFlags(); - } - - // TODO: setStaticVL(ElementCount) for scalable types. - - // Emit a VP intrinsic call that mimics a regular instruction. - // This operation behaves according to the VectorBuilderBehavior. - // \p Opcode The functional instruction opcode of the emitted intrinsic. - // \p ReturnTy The return type of the operation. - // \p VecOpArray The operand list. - LLVM_ABI Value *createVectorInstruction(unsigned Opcode, Type *ReturnTy, - ArrayRef VecOpArray, - const Twine &Name = Twine()); - - /// Emit a VP reduction intrinsic call for recurrence kind. - /// \param RdxID The intrinsic ID of llvm.vector.reduce.* - /// \param ValTy The type of operand which the reduction operation is - /// performed. - /// \param VecOpArray The operand list. - LLVM_ABI Value *createSimpleReduction(Intrinsic::ID RdxID, Type *ValTy, - ArrayRef VecOpArray, - const Twine &Name = Twine()); -}; - -} // namespace llvm - -#endif // LLVM_IR_VECTORBUILDER_H diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h index 6c0e06482a6de..12be3bad04d38 100644 --- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -16,7 +16,6 @@ #include "llvm/Analysis/IVDescriptors.h" #include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/IR/VectorBuilder.h" #include "llvm/Support/Compiler.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -423,8 +422,9 @@ LLVM_ABI Value *createSimpleReduction(IRBuilderBase &B, Value *Src, RecurKind RdxKind); /// Overloaded function to generate vector-predication intrinsics for /// reduction. -LLVM_ABI Value *createSimpleReduction(VectorBuilder &VB, Value *Src, - RecurKind RdxKind); +LLVM_ABI Value *createSimpleReduction(IRBuilderBase &B, Value *Src, + RecurKind RdxKind, Value *Mask, + Value *EVL); /// Create a reduction of the given vector \p Src for a reduction of kind /// RecurKind::AnyOf. The start value of the reduction is \p InitVal. @@ -442,8 +442,9 @@ LLVM_ABI Value *createOrderedReduction(IRBuilderBase &B, RecurKind RdxKind, Value *Src, Value *Start); /// Overloaded function to generate vector-predication intrinsics for ordered /// reduction. -LLVM_ABI Value *createOrderedReduction(VectorBuilder &VB, RecurKind RdxKind, - Value *Src, Value *Start); +LLVM_ABI Value *createOrderedReduction(IRBuilderBase &B, RecurKind RdxKind, + Value *Src, Value *Start, Value *Mask, + Value *EVL); /// Get the intersection (logical and) of all of the potential IR flags /// of each scalar operation (VL) that will be converted into a vector (I). diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt index eb00829fd8c70..10572ff708bd3 100644 --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -74,7 +74,6 @@ add_llvm_component_library(LLVMCore User.cpp Value.cpp ValueSymbolTable.cpp - VectorBuilder.cpp VectorTypeUtils.cpp Verifier.cpp VFABIDemangler.cpp diff --git a/llvm/lib/IR/VectorBuilder.cpp b/llvm/lib/IR/VectorBuilder.cpp deleted file mode 100644 index 737f49b1334d7..0000000000000 --- a/llvm/lib/IR/VectorBuilder.cpp +++ /dev/null @@ -1,116 +0,0 @@ -//===- VectorBuilder.cpp - Builder for VP Intrinsics ----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the VectorBuilder class, which is used as a convenient -// way to create VP intrinsics as if they were LLVM instructions with a -// consistent and simplified interface. -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include - -namespace llvm { - -void VectorBuilder::handleError(const char *ErrorMsg) const { - if (ErrorHandling == Behavior::SilentlyReturnNone) - return; - report_fatal_error(ErrorMsg); -} - -Module &VectorBuilder::getModule() const { - return *Builder.GetInsertBlock()->getModule(); -} - -Value *VectorBuilder::getAllTrueMask() { - return Builder.getAllOnesMask(StaticVectorLength); -} - -Value &VectorBuilder::requestMask() { - if (Mask) - return *Mask; - - return *getAllTrueMask(); -} - -Value &VectorBuilder::requestEVL() { - if (ExplicitVectorLength) - return *ExplicitVectorLength; - - assert(!StaticVectorLength.isScalable() && "TODO vscale lowering"); - auto *IntTy = Builder.getInt32Ty(); - return *ConstantInt::get(IntTy, StaticVectorLength.getFixedValue()); -} - -Value *VectorBuilder::createVectorInstruction(unsigned Opcode, Type *ReturnTy, - ArrayRef InstOpArray, - const Twine &Name) { - auto VPID = VPIntrinsic::getForOpcode(Opcode); - if (VPID == Intrinsic::not_intrinsic) - return returnWithError("No VPIntrinsic for this opcode"); - return createVectorInstructionImpl(VPID, ReturnTy, InstOpArray, Name); -} - -Value *VectorBuilder::createSimpleReduction(Intrinsic::ID RdxID, - Type *ValTy, - ArrayRef InstOpArray, - const Twine &Name) { - auto VPID = VPIntrinsic::getForIntrinsic(RdxID); - assert(VPReductionIntrinsic::isVPReduction(VPID) && - "No VPIntrinsic for this reduction"); - return createVectorInstructionImpl(VPID, ValTy, InstOpArray, Name); -} - -Value *VectorBuilder::createVectorInstructionImpl(Intrinsic::ID VPID, - Type *ReturnTy, - ArrayRef InstOpArray, - const Twine &Name) { - auto MaskPosOpt = VPIntrinsic::getMaskParamPos(VPID); - auto VLenPosOpt = VPIntrinsic::getVectorLengthParamPos(VPID); - size_t NumInstParams = InstOpArray.size(); - size_t NumVPParams = - NumInstParams + MaskPosOpt.has_value() + VLenPosOpt.has_value(); - - SmallVector IntrinParams; - - // Whether the mask and vlen parameter are at the end of the parameter list. - bool TrailingMaskAndVLen = - std::min(MaskPosOpt.value_or(NumInstParams), - VLenPosOpt.value_or(NumInstParams)) >= NumInstParams; - - if (TrailingMaskAndVLen) { - // Fast path for trailing mask, vector length. - IntrinParams.append(InstOpArray.begin(), InstOpArray.end()); - IntrinParams.resize(NumVPParams); - } else { - IntrinParams.resize(NumVPParams); - // Insert mask and evl operands in between the instruction operands. - for (size_t VPParamIdx = 0, ParamIdx = 0; VPParamIdx < NumVPParams; - ++VPParamIdx) { - if (MaskPosOpt == VPParamIdx || VLenPosOpt == VPParamIdx) - continue; - assert(ParamIdx < NumInstParams); - IntrinParams[VPParamIdx] = InstOpArray[ParamIdx++]; - } - } - - if (MaskPosOpt) - IntrinParams[*MaskPosOpt] = &requestMask(); - if (VLenPosOpt) - IntrinParams[*VLenPosOpt] = &requestEVL(); - - auto *VPDecl = VPIntrinsic::getOrInsertDeclarationForParams( - &getModule(), VPID, ReturnTy, IntrinParams); - return Builder.CreateCall(VPDecl, IntrinParams, Name); -} - -} // namespace llvm diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 0681ebc111cb2..ba02f44f9435a 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -1333,18 +1333,19 @@ Value *llvm::createSimpleReduction(IRBuilderBase &Builder, Value *Src, } } -Value *llvm::createSimpleReduction(VectorBuilder &VBuilder, Value *Src, - RecurKind Kind) { +Value *llvm::createSimpleReduction(IRBuilderBase &Builder, Value *Src, + RecurKind Kind, Value *Mask, Value *EVL) { assert(!RecurrenceDescriptor::isAnyOfRecurrenceKind(Kind) && !RecurrenceDescriptor::isFindLastIVRecurrenceKind(Kind) && "AnyOf or FindLastIV reductions are not supported."); Intrinsic::ID Id = getReductionIntrinsicID(Kind); - auto *SrcTy = cast(Src->getType()); - Type *SrcEltTy = SrcTy->getElementType(); - Value *Iden = - getRecurrenceIdentity(Kind, SrcEltTy, VBuilder.getFastMathFlags()); - Value *Ops[] = {Iden, Src}; - return VBuilder.createSimpleReduction(Id, SrcTy, Ops); + auto VPID = VPIntrinsic::getForIntrinsic(Id); + assert(VPReductionIntrinsic::isVPReduction(VPID) && + "No VPIntrinsic for this reduction"); + auto *EltTy = cast(Src->getType())->getElementType(); + Value *Iden = getRecurrenceIdentity(Kind, EltTy, Builder.getFastMathFlags()); + Value *Ops[] = {Iden, Src, Mask, EVL}; + return Builder.CreateIntrinsic(EltTy, VPID, Ops); } Value *llvm::createOrderedReduction(IRBuilderBase &B, RecurKind Kind, @@ -1357,17 +1358,21 @@ Value *llvm::createOrderedReduction(IRBuilderBase &B, RecurKind Kind, return B.CreateFAddReduce(Start, Src); } -Value *llvm::createOrderedReduction(VectorBuilder &VBuilder, RecurKind Kind, - Value *Src, Value *Start) { +Value *llvm::createOrderedReduction(IRBuilderBase &Builder, RecurKind Kind, + Value *Src, Value *Start, Value *Mask, + Value *EVL) { assert((Kind == RecurKind::FAdd || Kind == RecurKind::FMulAdd) && "Unexpected reduction kind"); assert(Src->getType()->isVectorTy() && "Expected a vector type"); assert(!Start->getType()->isVectorTy() && "Expected a scalar type"); Intrinsic::ID Id = getReductionIntrinsicID(RecurKind::FAdd); - auto *SrcTy = cast(Src->getType()); - Value *Ops[] = {Start, Src}; - return VBuilder.createSimpleReduction(Id, SrcTy, Ops); + auto VPID = VPIntrinsic::getForIntrinsic(Id); + assert(VPReductionIntrinsic::isVPReduction(VPID) && + "No VPIntrinsic for this reduction"); + auto *EltTy = cast(Src->getType())->getElementType(); + Value *Ops[] = {Start, Src, Mask, EVL}; + return Builder.CreateIntrinsic(EltTy, VPID, Ops); } void llvm::propagateIRFlags(Value *I, ArrayRef VL, Value *OpValue, diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 62b99d98a2b5e..13b1cfb37a292 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -30,7 +30,6 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" -#include "llvm/IR/VectorBuilder.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -2524,21 +2523,17 @@ void VPReductionEVLRecipe::execute(VPTransformState &State) { Value *VecOp = State.get(getVecOp()); Value *EVL = State.get(getEVL(), VPLane(0)); - VectorBuilder VBuilder(Builder); - VBuilder.setEVL(EVL); Value *Mask; - // TODO: move the all-true mask generation into VectorBuilder. if (VPValue *CondOp = getCondOp()) Mask = State.get(CondOp); else Mask = Builder.CreateVectorSplat(State.VF, Builder.getTrue()); - VBuilder.setMask(Mask); Value *NewRed; if (isOrdered()) { - NewRed = createOrderedReduction(VBuilder, Kind, VecOp, Prev); + NewRed = createOrderedReduction(Builder, Kind, VecOp, Prev, Mask, EVL); } else { - NewRed = createSimpleReduction(VBuilder, VecOp, Kind); + NewRed = createSimpleReduction(Builder, VecOp, Kind, Mask, EVL); if (RecurrenceDescriptor::isMinMaxRecurrenceKind(Kind)) NewRed = createMinMaxOp(Builder, Kind, NewRed, Prev); else @@ -3086,10 +3081,8 @@ void VPWidenLoadEVLRecipe::execute(VPTransformState &State) { Builder.CreateIntrinsic(DataTy, Intrinsic::vp_gather, {Addr, Mask, EVL}, nullptr, "wide.masked.gather"); } else { - VectorBuilder VBuilder(Builder); - VBuilder.setEVL(EVL).setMask(Mask); - NewLI = cast(VBuilder.createVectorInstruction( - Instruction::Load, DataTy, Addr, "vp.op.load")); + NewLI = Builder.CreateIntrinsic(DataTy, Intrinsic::vp_load, + {Addr, Mask, EVL}, nullptr, "vp.op.load"); } NewLI->addParamAttr( 0, Attribute::getWithAlignment(NewLI->getContext(), Alignment)); @@ -3204,11 +3197,9 @@ void VPWidenStoreEVLRecipe::execute(VPTransformState &State) { Intrinsic::vp_scatter, {StoredVal, Addr, Mask, EVL}); } else { - VectorBuilder VBuilder(Builder); - VBuilder.setEVL(EVL).setMask(Mask); - NewSI = cast(VBuilder.createVectorInstruction( - Instruction::Store, Type::getVoidTy(EVL->getContext()), - {StoredVal, Addr})); + NewSI = Builder.CreateIntrinsic(Type::getVoidTy(EVL->getContext()), + Intrinsic::vp_store, + {StoredVal, Addr, Mask, EVL}); } NewSI->addParamAttr( 1, Attribute::getWithAlignment(NewSI->getContext(), Alignment)); diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt index bea6b1b46f573..b66eae93f9339 100644 --- a/llvm/unittests/IR/CMakeLists.txt +++ b/llvm/unittests/IR/CMakeLists.txt @@ -50,7 +50,6 @@ add_llvm_unittest(IRTests ValueHandleTest.cpp ValueMapTest.cpp ValueTest.cpp - VectorBuilderTest.cpp VectorTypeUtilsTest.cpp VectorTypesTest.cpp VerifierTest.cpp diff --git a/llvm/unittests/IR/VectorBuilderTest.cpp b/llvm/unittests/IR/VectorBuilderTest.cpp deleted file mode 100644 index e01378a2755f0..0000000000000 --- a/llvm/unittests/IR/VectorBuilderTest.cpp +++ /dev/null @@ -1,279 +0,0 @@ -//===--------- VectorBuilderTest.cpp - VectorBuilder unit tests -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/IR/VectorBuilder.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { - -static unsigned VectorNumElements = 8; - -class VectorBuilderTest : public testing::Test { -protected: - LLVMContext Context; - - VectorBuilderTest() : Context() {} - - std::unique_ptr createBuilderModule(Function *&Func, BasicBlock *&BB, - Value *&Mask, Value *&EVL) { - auto Mod = std::make_unique("TestModule", Context); - auto *Int32Ty = Type::getInt32Ty(Context); - auto *Mask8Ty = - FixedVectorType::get(Type::getInt1Ty(Context), VectorNumElements); - auto *VoidFuncTy = - FunctionType::get(Type::getVoidTy(Context), {Mask8Ty, Int32Ty}, false); - Func = - Function::Create(VoidFuncTy, GlobalValue::ExternalLinkage, "bla", *Mod); - Mask = Func->getArg(0); - EVL = Func->getArg(1); - BB = BasicBlock::Create(Context, "entry", Func); - - return Mod; - } -}; - -/// Check that creating binary arithmetic VP intrinsics works. -TEST_F(VectorBuilderTest, TestCreateBinaryInstructions) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - VectorBuilder VBuild(Builder); - VBuild.setMask(Mask).setEVL(EVL); - - auto *FloatVecTy = - FixedVectorType::get(Type::getFloatTy(Context), VectorNumElements); - auto *IntVecTy = - FixedVectorType::get(Type::getInt32Ty(Context), VectorNumElements); - -#define HANDLE_BINARY_INST(NUM, OPCODE, INSTCLASS) \ - { \ - auto VPID = VPIntrinsic::getForOpcode(Instruction::OPCODE); \ - bool IsFP = (#INSTCLASS)[0] == 'F'; \ - auto *ValueTy = IsFP ? FloatVecTy : IntVecTy; \ - Value *Op = PoisonValue::get(ValueTy); \ - auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \ - {Op, Op}); \ - ASSERT_TRUE(isa(I)); \ - auto *VPIntrin = cast(I); \ - ASSERT_EQ(VPIntrin->getIntrinsicID(), VPID); \ - ASSERT_EQ(VPIntrin->getMaskParam(), Mask); \ - ASSERT_EQ(VPIntrin->getVectorLengthParam(), EVL); \ - } -#include "llvm/IR/Instruction.def" -} - -static bool isAllTrueMask(Value *Val, unsigned NumElements) { - auto *ConstMask = dyn_cast(Val); - if (!ConstMask) - return false; - - // Structure check. - if (!ConstMask->isAllOnesValue()) - return false; - - // Type check. - auto *MaskVecTy = cast(ConstMask->getType()); - if (MaskVecTy->getNumElements() != NumElements) - return false; - - return MaskVecTy->getElementType()->isIntegerTy(1); -} - -/// Check that creating binary arithmetic VP intrinsics works. -TEST_F(VectorBuilderTest, TestCreateBinaryInstructions_FixedVector_NoMask) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - VectorBuilder VBuild(Builder); - VBuild.setEVL(EVL).setStaticVL(VectorNumElements); - - auto *FloatVecTy = - FixedVectorType::get(Type::getFloatTy(Context), VectorNumElements); - auto *IntVecTy = - FixedVectorType::get(Type::getInt32Ty(Context), VectorNumElements); - -#define HANDLE_BINARY_INST(NUM, OPCODE, INSTCLASS) \ - { \ - auto VPID = VPIntrinsic::getForOpcode(Instruction::OPCODE); \ - bool IsFP = (#INSTCLASS)[0] == 'F'; \ - Type *ValueTy = IsFP ? FloatVecTy : IntVecTy; \ - Value *Op = PoisonValue::get(ValueTy); \ - auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \ - {Op, Op}); \ - ASSERT_TRUE(isa(I)); \ - auto *VPIntrin = cast(I); \ - ASSERT_EQ(VPIntrin->getIntrinsicID(), VPID); \ - ASSERT_TRUE(isAllTrueMask(VPIntrin->getMaskParam(), VectorNumElements)); \ - ASSERT_EQ(VPIntrin->getVectorLengthParam(), EVL); \ - } -#include "llvm/IR/Instruction.def" -} - -static bool isLegalConstEVL(Value *Val, unsigned ExpectedEVL) { - auto *ConstEVL = dyn_cast(Val); - if (!ConstEVL) - return false; - - // Value check. - if (ConstEVL->getZExtValue() != ExpectedEVL) - return false; - - // Type check. - return ConstEVL->getType()->isIntegerTy(32); -} - -/// Check that creating binary arithmetic VP intrinsics works. -TEST_F(VectorBuilderTest, TestCreateBinaryInstructions_FixedVector_NoEVL) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - VectorBuilder VBuild(Builder); - VBuild.setMask(Mask).setStaticVL(VectorNumElements); - - auto *FloatVecTy = - FixedVectorType::get(Type::getFloatTy(Context), VectorNumElements); - auto *IntVecTy = - FixedVectorType::get(Type::getInt32Ty(Context), VectorNumElements); - -#define HANDLE_BINARY_INST(NUM, OPCODE, INSTCLASS) \ - { \ - auto VPID = VPIntrinsic::getForOpcode(Instruction::OPCODE); \ - bool IsFP = (#INSTCLASS)[0] == 'F'; \ - Type *ValueTy = IsFP ? FloatVecTy : IntVecTy; \ - Value *Op = PoisonValue::get(ValueTy); \ - auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \ - {Op, Op}); \ - ASSERT_TRUE(isa(I)); \ - auto *VPIntrin = cast(I); \ - ASSERT_EQ(VPIntrin->getIntrinsicID(), VPID); \ - ASSERT_EQ(VPIntrin->getMaskParam(), Mask); \ - ASSERT_TRUE( \ - isLegalConstEVL(VPIntrin->getVectorLengthParam(), VectorNumElements)); \ - } -#include "llvm/IR/Instruction.def" -} - -/// Check that creating binary arithmetic VP intrinsics works. -TEST_F(VectorBuilderTest, - TestCreateBinaryInstructions_FixedVector_NoMask_NoEVL) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - VectorBuilder VBuild(Builder); - VBuild.setStaticVL(VectorNumElements); - - auto *FloatVecTy = - FixedVectorType::get(Type::getFloatTy(Context), VectorNumElements); - auto *IntVecTy = - FixedVectorType::get(Type::getInt32Ty(Context), VectorNumElements); - -#define HANDLE_BINARY_INST(NUM, OPCODE, INSTCLASS) \ - { \ - auto VPID = VPIntrinsic::getForOpcode(Instruction::OPCODE); \ - bool IsFP = (#INSTCLASS)[0] == 'F'; \ - Type *ValueTy = IsFP ? FloatVecTy : IntVecTy; \ - Value *Op = PoisonValue::get(ValueTy); \ - auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \ - {Op, Op}); \ - ASSERT_TRUE(isa(I)); \ - auto *VPIntrin = cast(I); \ - ASSERT_EQ(VPIntrin->getIntrinsicID(), VPID); \ - ASSERT_TRUE(isAllTrueMask(VPIntrin->getMaskParam(), VectorNumElements)); \ - ASSERT_TRUE( \ - isLegalConstEVL(VPIntrin->getVectorLengthParam(), VectorNumElements)); \ - } -#include "llvm/IR/Instruction.def" -} -/// Check that creating vp.load/vp.store works. -TEST_F(VectorBuilderTest, TestCreateLoadStore) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - VectorBuilder VBuild(Builder); - VBuild.setMask(Mask).setEVL(EVL); - - auto *FloatVecTy = - FixedVectorType::get(Type::getFloatTy(Context), VectorNumElements); - - Value *FloatVecPtr = PoisonValue::get(Builder.getPtrTy(0)); - Value *FloatVec = PoisonValue::get(FloatVecTy); - - // vp.load - auto LoadVPID = VPIntrinsic::getForOpcode(Instruction::Load); - auto *LoadIntrin = VBuild.createVectorInstruction(Instruction::Load, - FloatVecTy, {FloatVecPtr}); - ASSERT_TRUE(isa(LoadIntrin)); - auto *VPLoad = cast(LoadIntrin); - ASSERT_EQ(VPLoad->getIntrinsicID(), LoadVPID); - ASSERT_EQ(VPLoad->getMemoryPointerParam(), FloatVecPtr); - - // vp.store - auto *VoidTy = Builder.getVoidTy(); - auto StoreVPID = VPIntrinsic::getForOpcode(Instruction::Store); - auto *StoreIntrin = VBuild.createVectorInstruction(Instruction::Store, VoidTy, - {FloatVec, FloatVecPtr}); - ASSERT_TRUE(isa(LoadIntrin)); - auto *VPStore = cast(StoreIntrin); - ASSERT_EQ(VPStore->getIntrinsicID(), StoreVPID); - ASSERT_EQ(VPStore->getMemoryPointerParam(), FloatVecPtr); - ASSERT_EQ(VPStore->getMemoryDataParam(), FloatVec); -} - -/// Check that the SilentlyReturnNone error handling mode works. -TEST_F(VectorBuilderTest, TestFail_SilentlyReturnNone) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - auto *VoidTy = Builder.getVoidTy(); - VectorBuilder VBuild(Builder, VectorBuilder::Behavior::SilentlyReturnNone); - VBuild.setMask(Mask).setEVL(EVL); - auto *Val = VBuild.createVectorInstruction(Instruction::Br, VoidTy, {}); - ASSERT_EQ(Val, nullptr); -} - -/// Check that the ReportAndFail error handling mode aborts as advertised. -TEST_F(VectorBuilderTest, TestFail_ReportAndAbort) { - Function *F; - BasicBlock *BB; - Value *Mask, *EVL; - auto Mod = createBuilderModule(F, BB, Mask, EVL); - - IRBuilder<> Builder(BB); - auto *VoidTy = Builder.getVoidTy(); - VectorBuilder VBuild(Builder, VectorBuilder::Behavior::ReportAndAbort); - VBuild.setMask(Mask).setEVL(EVL); - ASSERT_DEATH({ VBuild.createVectorInstruction(Instruction::Br, VoidTy, {}); }, - "No VPIntrinsic for this opcode"); -} - -} // end anonymous namespace