[llvm] 5f62156 - [VP] Introducing VectorBuilder, the VP intrinsic builder
Simon Moll via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 7 01:03:15 PST 2022
Author: Simon Moll
Date: 2022-03-07T10:02:07+01:00
New Revision: 5f62156762d45f53fa70446c718813f9f9a099e5
URL: https://github.com/llvm/llvm-project/commit/5f62156762d45f53fa70446c718813f9f9a099e5
DIFF: https://github.com/llvm/llvm-project/commit/5f62156762d45f53fa70446c718813f9f9a099e5.diff
LOG: [VP] Introducing VectorBuilder, the VP intrinsic builder
VectorBuilder wraps around an IRBuilder and
VectorBuilder::createVectorInstructions emits VP intrinsics as if they
were regular instructions.
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D105283
Added:
llvm/include/llvm/IR/VectorBuilder.h
llvm/lib/IR/VectorBuilder.cpp
llvm/unittests/IR/VectorBuilderTest.cpp
Modified:
llvm/include/llvm/module.modulemap
llvm/lib/IR/CMakeLists.txt
llvm/unittests/IR/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/VectorBuilder.h b/llvm/include/llvm/IR/VectorBuilder.h
new file mode 100644
index 0000000000000..a24338adf3c5d
--- /dev/null
+++ b/llvm/include/llvm/IR/VectorBuilder.h
@@ -0,0 +1,99 @@
+//===- 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/IR/IRBuilder.h>
+#include <llvm/IR/InstrTypes.h>
+#include <llvm/IR/Instruction.h>
+#include <llvm/IR/Value.h>
+
+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:
+ IRBuilder<> &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();
+
+ void handleError(const char *ErrorMsg) const;
+ template <typename RetType>
+ RetType returnWithError(const char *ErrorMsg) const {
+ handleError(ErrorMsg);
+ return RetType();
+ }
+
+public:
+ VectorBuilder(IRBuilder<> &Builder,
+ Behavior ErrorHandling = Behavior::ReportAndAbort)
+ : Builder(Builder), ErrorHandling(ErrorHandling), Mask(nullptr),
+ ExplicitVectorLength(nullptr),
+ StaticVectorLength(ElementCount::getFixed(0)) {}
+
+ Module &getModule() const;
+ LLVMContext &getContext() const { return Builder.getContext(); }
+
+ // All-true mask for the currently configured explicit vector length.
+ 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;
+ }
+ // 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.
+ Value *createVectorInstruction(unsigned Opcode, Type *ReturnTy,
+ ArrayRef<Value *> VecOpArray,
+ const Twine &Name = Twine());
+};
+
+} // namespace llvm
+
+#endif // LLVM_IR_VECTORBUILDER_H
diff --git a/llvm/include/llvm/module.modulemap b/llvm/include/llvm/module.modulemap
index 2e6bf791330d1..c94bece5c0985 100644
--- a/llvm/include/llvm/module.modulemap
+++ b/llvm/include/llvm/module.modulemap
@@ -254,6 +254,7 @@ module LLVM_intrinsic_gen {
module IR_InstrTypes { header "IR/InstrTypes.h" export * }
module IR_Instructions { header "IR/Instructions.h" export * }
module IR_TypeFinder { header "IR/TypeFinder.h" export * }
+ module IR_VectorBuilder { header "IR/VectorBuilder.h" export * }
// Intrinsics.h
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 2c09e57c3f970..3e542e4622fbd 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -61,6 +61,7 @@ add_llvm_component_library(LLVMCore
User.cpp
Value.cpp
ValueSymbolTable.cpp
+ VectorBuilder.cpp
Verifier.cpp
ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/IR/VectorBuilder.cpp b/llvm/lib/IR/VectorBuilder.cpp
new file mode 100644
index 0000000000000..34d943a9b10b4
--- /dev/null
+++ b/llvm/lib/IR/VectorBuilder.cpp
@@ -0,0 +1,103 @@
+//===- 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 <llvm/ADT/SmallVector.h>
+#include <llvm/IR/FPEnv.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/IntrinsicInst.h>
+#include <llvm/IR/Intrinsics.h>
+#include <llvm/IR/VectorBuilder.h>
+
+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() {
+ auto *BoolTy = Builder.getInt1Ty();
+ auto *MaskTy = VectorType::get(BoolTy, StaticVectorLength);
+ return ConstantInt::getAllOnesValue(MaskTy);
+}
+
+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<Value *> InstOpArray,
+ const Twine &Name) {
+ auto VPID = VPIntrinsic::getForOpcode(Opcode);
+ if (VPID == Intrinsic::not_intrinsic)
+ return returnWithError<Value *>("No VPIntrinsic for this opcode");
+
+ auto MaskPosOpt = VPIntrinsic::getMaskParamPos(VPID);
+ auto VLenPosOpt = VPIntrinsic::getVectorLengthParamPos(VPID);
+ size_t NumInstParams = InstOpArray.size();
+ size_t NumVPParams =
+ NumInstParams + MaskPosOpt.hasValue() + VLenPosOpt.hasValue();
+
+ SmallVector<Value *, 6> IntrinParams;
+
+ // Whether the mask and vlen parameter are at the end of the parameter list.
+ bool TrailingMaskAndVLen =
+ std::min<size_t>(MaskPosOpt.getValueOr(NumInstParams),
+ VLenPosOpt.getValueOr(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 && MaskPosOpt.getValueOr(NumVPParams) == VPParamIdx) ||
+ (VLenPosOpt && VLenPosOpt.getValueOr(NumVPParams) == VPParamIdx))
+ continue;
+ assert(ParamIdx < NumInstParams);
+ IntrinParams[VPParamIdx] = InstOpArray[ParamIdx++];
+ }
+ }
+
+ if (MaskPosOpt.hasValue())
+ IntrinParams[*MaskPosOpt] = &requestMask();
+ if (VLenPosOpt.hasValue())
+ IntrinParams[*VLenPosOpt] = &requestEVL();
+
+ auto *VPDecl = VPIntrinsic::getDeclarationForParams(&getModule(), VPID,
+ ReturnTy, IntrinParams);
+ return Builder.CreateCall(VPDecl, IntrinParams, Name);
+}
+
+} // namespace llvm
diff --git a/llvm/unittests/IR/CMakeLists.txt b/llvm/unittests/IR/CMakeLists.txt
index 42fa677b24721..e9f3d5598d142 100644
--- a/llvm/unittests/IR/CMakeLists.txt
+++ b/llvm/unittests/IR/CMakeLists.txt
@@ -41,6 +41,7 @@ add_llvm_unittest(IRTests
ValueHandleTest.cpp
ValueMapTest.cpp
ValueTest.cpp
+ VectorBuilderTest.cpp
VectorTypesTest.cpp
VerifierTest.cpp
VPIntrinsicTest.cpp
diff --git a/llvm/unittests/IR/VectorBuilderTest.cpp b/llvm/unittests/IR/VectorBuilderTest.cpp
new file mode 100644
index 0000000000000..82ce045ab4b05
--- /dev/null
+++ b/llvm/unittests/IR/VectorBuilderTest.cpp
@@ -0,0 +1,280 @@
+//===--------- 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<Module> createBuilderModule(Function *&Func, BasicBlock *&BB,
+ Value *&Mask, Value *&EVL) {
+ auto Mod = std::make_unique<Module>("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 = UndefValue::get(ValueTy); \
+ auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \
+ {Op, Op}); \
+ ASSERT_TRUE(isa<VPIntrinsic>(I)); \
+ auto *VPIntrin = cast<VPIntrinsic>(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<Constant>(Val);
+ if (!ConstMask)
+ return false;
+
+ // Structure check.
+ if (!ConstMask->isAllOnesValue())
+ return false;
+
+ // Type check.
+ auto *MaskVecTy = cast<FixedVectorType>(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 = UndefValue::get(ValueTy); \
+ auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \
+ {Op, Op}); \
+ ASSERT_TRUE(isa<VPIntrinsic>(I)); \
+ auto *VPIntrin = cast<VPIntrinsic>(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<ConstantInt>(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 = UndefValue::get(ValueTy); \
+ auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \
+ {Op, Op}); \
+ ASSERT_TRUE(isa<VPIntrinsic>(I)); \
+ auto *VPIntrin = cast<VPIntrinsic>(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 = UndefValue::get(ValueTy); \
+ auto *I = VBuild.createVectorInstruction(Instruction::OPCODE, ValueTy, \
+ {Op, Op}); \
+ ASSERT_TRUE(isa<VPIntrinsic>(I)); \
+ auto *VPIntrin = cast<VPIntrinsic>(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);
+ auto *FloatVecPtrTy = FloatVecTy->getPointerTo();
+
+ Value *FloatVecPtr = UndefValue::get(FloatVecPtrTy);
+ Value *FloatVec = UndefValue::get(FloatVecTy);
+
+ // vp.load
+ auto LoadVPID = VPIntrinsic::getForOpcode(Instruction::Load);
+ auto *LoadIntrin = VBuild.createVectorInstruction(Instruction::Load,
+ FloatVecTy, {FloatVecPtr});
+ ASSERT_TRUE(isa<VPIntrinsic>(LoadIntrin));
+ auto *VPLoad = cast<VPIntrinsic>(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<VPIntrinsic>(LoadIntrin));
+ auto *VPStore = cast<VPIntrinsic>(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
More information about the llvm-commits
mailing list