diff options
Diffstat (limited to 'llvm/unittests')
20 files changed, 935 insertions, 503 deletions
diff --git a/llvm/unittests/Analysis/IR2VecTest.cpp b/llvm/unittests/Analysis/IR2VecTest.cpp index 7c9a546..e288585 100644 --- a/llvm/unittests/Analysis/IR2VecTest.cpp +++ b/llvm/unittests/Analysis/IR2VecTest.cpp @@ -364,9 +364,9 @@ TEST_F(IR2VecTestFixture, GetFunctionVector) { EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 44.4))); } -static constexpr unsigned MaxOpcodes = 67; -static constexpr unsigned MaxTypeIDs = 21; -static constexpr unsigned MaxOperands = 4; +static constexpr unsigned MaxOpcodes = Vocabulary::MaxOpcodes; +static constexpr unsigned MaxTypeIDs = Vocabulary::MaxTypeIDs; +static constexpr unsigned MaxOperands = Vocabulary::MaxOperandKinds; TEST(IR2VecVocabularyTest, DummyVocabTest) { for (unsigned Dim = 1; Dim <= 10; ++Dim) { diff --git a/llvm/unittests/Analysis/InlineAdvisorPlugin/CMakeLists.txt b/llvm/unittests/Analysis/InlineAdvisorPlugin/CMakeLists.txt index deabf11..d9da627 100644 --- a/llvm/unittests/Analysis/InlineAdvisorPlugin/CMakeLists.txt +++ b/llvm/unittests/Analysis/InlineAdvisorPlugin/CMakeLists.txt @@ -2,7 +2,7 @@ # libraries, but expects them to exist in the process loading the plugin. This # doesn't work with DLLs on Windows (where a shared library can't have undefined # references), so just skip this testcase on Windows. -if ((NOT WIN32 OR LLVM_BUILD_LLVM_DYLIB) AND NOT CYGWIN) +if ((NOT WIN32 AND NOT CYGWIN) OR LLVM_BUILD_LLVM_DYLIB) unset(LLVM_LINK_COMPONENTS) add_llvm_library(InlineAdvisorPlugin MODULE BUILDTREE_ONLY InlineAdvisorPlugin.cpp diff --git a/llvm/unittests/Analysis/InlineOrderPlugin/CMakeLists.txt b/llvm/unittests/Analysis/InlineOrderPlugin/CMakeLists.txt index 0b37ceb..941e18efc 100644 --- a/llvm/unittests/Analysis/InlineOrderPlugin/CMakeLists.txt +++ b/llvm/unittests/Analysis/InlineOrderPlugin/CMakeLists.txt @@ -2,7 +2,7 @@ # libraries, but expects them to exist in the process loading the plugin. This # doesn't work with DLLs on Windows (where a shared library can't have undefined # references), so just skip this testcase on Windows. -if ((NOT WIN32 OR LLVM_BUILD_LLVM_DYLIB) AND NOT CYGWIN) +if ((NOT WIN32 AND NOT CYGWIN) OR LLVM_BUILD_LLVM_DYLIB) unset(LLVM_LINK_COMPONENTS) add_llvm_library(InlineOrderPlugin MODULE BUILDTREE_ONLY InlineOrderPlugin.cpp diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt index d19b122..22dbdaa 100644 --- a/llvm/unittests/CodeGen/CMakeLists.txt +++ b/llvm/unittests/CodeGen/CMakeLists.txt @@ -42,6 +42,7 @@ add_llvm_unittest(CodeGenTests ScalableVectorMVTsTest.cpp SchedBoundary.cpp SelectionDAGAddressAnalysisTest.cpp + SelectionDAGNodeConstructionTest.cpp SelectionDAGPatternMatchTest.cpp TypeTraitsTest.cpp TargetOptionsTest.cpp diff --git a/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp b/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp index 36504f5..e72b4e4 100644 --- a/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp +++ b/llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp @@ -39,8 +39,7 @@ createTargetMachine(std::string TargetStr, StringRef CPU, StringRef FS) { return nullptr; TargetOptions Options; return std::unique_ptr<TargetMachine>( - static_cast<TargetMachine *>(T->createTargetMachine( - TT, CPU, FS, Options, std::nullopt, std::nullopt))); + T->createTargetMachine(TT, CPU, FS, Options, std::nullopt, std::nullopt)); } std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode, diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp index 7928c91..c5992eb 100644 --- a/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp @@ -78,7 +78,7 @@ TEST_F(AArch64GISelMITest, BasicLegalizerTest) { CHECK: %vptr:_(p0) = COPY $x4 CHECK-NEXT: [[LOAD_0:%[0-9]+]]:_(s16) = G_LOAD %vptr:_(p0) :: (load (s8)) CHECK-NEXT: [[OFFSET_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - CHECK-NEXT: [[VPTR_1:%[0-9]+]]:_(p0) = G_PTR_ADD %vptr:_, [[OFFSET_1]]:_(s64) + CHECK-NEXT: [[VPTR_1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD %vptr:_, [[OFFSET_1]]:_(s64) CHECK-NEXT: [[LOAD_1:%[0-9]+]]:_(s16) = G_LOAD [[VPTR_1]]:_(p0) :: (load (s8) from unknown-address + 1) CHECK-NEXT: %v:_(<2 x s8>) = G_BUILD_VECTOR_TRUNC [[LOAD_0]]:_(s16), [[LOAD_1]]:_(s16) CHECK-NEXT: $h4 = COPY %v:_(<2 x s8>) @@ -210,7 +210,7 @@ TEST_F(AArch64GISelMITest, UnorderedArtifactCombiningManyCopiesTest) { CHECK: %vptr:_(p0) = COPY $x4 CHECK-NEXT: [[LOAD_0:%[0-9]+]]:_(s16) = G_LOAD %vptr:_(p0) :: (load (s8)) CHECK-NEXT: [[OFFSET_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - CHECK-NEXT: [[VPTR_1:%[0-9]+]]:_(p0) = G_PTR_ADD %vptr:_, [[OFFSET_1]]:_(s64) + CHECK-NEXT: [[VPTR_1:%[0-9]+]]:_(p0) = nuw inbounds G_PTR_ADD %vptr:_, [[OFFSET_1]]:_(s64) CHECK-NEXT: [[LOAD_1:%[0-9]+]]:_(s16) = G_LOAD [[VPTR_1]]:_(p0) :: (load (s8) from unknown-address + 1) CHECK-NEXT: [[V0_EXT:%[0-9]+]]:_(s32) = G_ANYEXT [[LOAD_0]]:_(s16) CHECK-NEXT: [[FF_MASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 diff --git a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp index 0058daf..7ad7a51 100644 --- a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp @@ -7,103 +7,12 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" +#include "SelectionDAGTestBase.h" #include "llvm/Analysis/MemoryLocation.h" -#include "llvm/Analysis/OptimizationRemarkEmitter.h" -#include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/AsmParser/Parser.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetMachine.h" -#include "gtest/gtest.h" namespace llvm { -class SelectionDAGAddressAnalysisTest : public testing::Test { -protected: - static void SetUpTestCase() { - InitializeAllTargets(); - InitializeAllTargetMCs(); - } - - void SetUp() override { - StringRef Assembly = "@g = global i32 0\n" - "@g_alias = alias i32, i32* @g\n" - "define i32 @f() {\n" - " %1 = load i32, i32* @g\n" - " ret i32 %1\n" - "}"; - - Triple TargetTriple("aarch64--"); - std::string Error; - const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); - // FIXME: These tests do not depend on AArch64 specifically, but we have to - // initialize a target. A skeleton Target for unittests would allow us to - // always run these tests. - if (!T) - GTEST_SKIP(); - - TargetOptions Options; - TM = std::unique_ptr<TargetMachine>( - T->createTargetMachine(TargetTriple, "", "+sve", Options, std::nullopt, - std::nullopt, CodeGenOptLevel::Aggressive)); - if (!TM) - GTEST_SKIP(); - - SMDiagnostic SMError; - M = parseAssemblyString(Assembly, SMError, Context); - if (!M) - report_fatal_error(SMError.getMessage()); - M->setDataLayout(TM->createDataLayout()); - - F = M->getFunction("f"); - if (!F) - report_fatal_error("F?"); - G = M->getGlobalVariable("g"); - if (!G) - report_fatal_error("G?"); - AliasedG = M->getNamedAlias("g_alias"); - if (!AliasedG) - report_fatal_error("AliasedG?"); - - MachineModuleInfo MMI(TM.get()); - - MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), - MMI.getContext(), 0); - - DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); - if (!DAG) - report_fatal_error("DAG?"); - OptimizationRemarkEmitter ORE(F); - FunctionAnalysisManager FAM; - FAM.registerPass([&] { return TM->getTargetIRAnalysis(); }); - - TargetTransformInfo TTI = TM->getTargetIRAnalysis().run(*F, FAM); - DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI, - nullptr, TTI.hasBranchDivergence(F)); - } - - TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { - return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); - } - - EVT getTypeToTransformTo(EVT VT) { - return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); - } - - LLVMContext Context; - std::unique_ptr<TargetMachine> TM; - std::unique_ptr<Module> M; - Function *F; - GlobalVariable *G; - GlobalAlias *AliasedG; - std::unique_ptr<MachineFunction> MF; - std::unique_ptr<SelectionDAG> DAG; -}; +class SelectionDAGAddressAnalysisTest : public SelectionDAGTestBase {}; TEST_F(SelectionDAGAddressAnalysisTest, sameFrameObject) { SDLoc Loc; diff --git a/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp new file mode 100644 index 0000000..b2c1420 --- /dev/null +++ b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp @@ -0,0 +1,317 @@ +//===---- llvm/unittest/CodeGen/SelectionDAGPatternMatchTest.cpp ----------===// +// +// 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 "SelectionDAGTestBase.h" + +using namespace llvm; + +class SelectionDAGNodeConstructionTest : public SelectionDAGTestBase {}; + +TEST_F(SelectionDAGNodeConstructionTest, ADD) { + SDLoc DL; + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Op, Undef), Undef); + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Undef, Op), Undef); + EXPECT_EQ(DAG->getNode(ISD::ADD, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, AND) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Op, Undef), Zero); + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::AND, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, MUL) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Op, Undef), Zero); + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::MUL, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, OR) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue AllOnes = DAG->getAllOnesConstant(DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Op, Undef), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Undef, Op), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::OR, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, SADDSAT) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue AllOnes = DAG->getAllOnesConstant(DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Op, Undef), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Undef, Op), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::SADDSAT, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, SDIV) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Op, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::SDIV, DL, MVT::i32, Undef, Undef), Poison); +} + +TEST_F(SelectionDAGNodeConstructionTest, SMAX) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue MaxInt = DAG->getConstant(APInt::getSignedMaxValue(32), DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Op, Undef), MaxInt); + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Undef, Op), MaxInt); + EXPECT_EQ(DAG->getNode(ISD::SMAX, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, SMIN) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue MinInt = DAG->getConstant(APInt::getSignedMinValue(32), DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Op, Undef), MinInt); + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Undef, Op), MinInt); + EXPECT_EQ(DAG->getNode(ISD::SMIN, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, SREM) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Op, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::SREM, DL, MVT::i32, Undef, Undef), Poison); +} + +TEST_F(SelectionDAGNodeConstructionTest, SSUBSAT) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Op, Undef), Zero); + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::SSUBSAT, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, SUB) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Op, Undef), Undef); + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Undef, Op), Undef); + EXPECT_EQ(DAG->getNode(ISD::SUB, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, UADDSAT) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue AllOnes = DAG->getAllOnesConstant(DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Op, Undef), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Undef, Op), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::UADDSAT, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, UDIV) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Op, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::UDIV, DL, MVT::i32, Undef, Undef), Poison); +} + +TEST_F(SelectionDAGNodeConstructionTest, UMAX) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue AllOnes = DAG->getAllOnesConstant(DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Op, Undef), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Undef, Op), AllOnes); + EXPECT_EQ(DAG->getNode(ISD::UMAX, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, UMIN) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Op, Undef), Zero); + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::UMIN, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, UREM) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Op, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::UREM, DL, MVT::i32, Undef, Undef), Poison); +} + +TEST_F(SelectionDAGNodeConstructionTest, USUBSAT) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Op, Undef), Zero); + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Undef, Op), Zero); + EXPECT_EQ(DAG->getNode(ISD::USUBSAT, DL, MVT::i32, Undef, Undef), Undef); +} + +TEST_F(SelectionDAGNodeConstructionTest, XOR) { + SDLoc DL; + SDValue Op = DAG->getCopyFromReg(DAG->getEntryNode(), DL, 1, MVT::i32); + SDValue Poison = DAG->getPOISON(MVT::i32); + SDValue Undef = DAG->getUNDEF(MVT::i32); + SDValue Zero = DAG->getConstant(0, DL, MVT::i32); + + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Op, Poison), Poison); + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Poison, Op), Poison); + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Poison, Undef), Poison); + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Undef, Poison), Poison); + + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Op, Undef), Undef); + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Undef, Op), Undef); + EXPECT_EQ(DAG->getNode(ISD::XOR, DL, MVT::i32, Undef, Undef), Zero); +} diff --git a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp index 30a1406..4e0bf38 100644 --- a/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp @@ -6,102 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/OptimizationRemarkEmitter.h" -#include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/AsmParser/Parser.h" -#include "llvm/CodeGen/MachineModuleInfo.h" +#include "SelectionDAGTestBase.h" #include "llvm/CodeGen/SDPatternMatch.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Target/TargetMachine.h" -#include "gtest/gtest.h" using namespace llvm; -class SelectionDAGPatternMatchTest : public testing::Test { -protected: - static void SetUpTestCase() { - InitializeAllTargets(); - InitializeAllTargetMCs(); - } - - void SetUp() override { - StringRef Assembly = "@g = global i32 0\n" - "@g_alias = alias i32, i32* @g\n" - "define i32 @f() {\n" - " %1 = load i32, i32* @g\n" - " ret i32 %1\n" - "}"; - - Triple TargetTriple("riscv64--"); - std::string Error; - const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); - // FIXME: These tests do not depend on RISCV specifically, but we have to - // initialize a target. A skeleton Target for unittests would allow us to - // always run these tests. - if (!T) - GTEST_SKIP(); - - TargetOptions Options; - TM = std::unique_ptr<TargetMachine>(T->createTargetMachine( - TargetTriple, "", "+m,+f,+d,+v", Options, std::nullopt, std::nullopt, - CodeGenOptLevel::Aggressive)); - if (!TM) - GTEST_SKIP(); - - SMDiagnostic SMError; - M = parseAssemblyString(Assembly, SMError, Context); - if (!M) - report_fatal_error(SMError.getMessage()); - M->setDataLayout(TM->createDataLayout()); - - F = M->getFunction("f"); - if (!F) - report_fatal_error("F?"); - G = M->getGlobalVariable("g"); - if (!G) - report_fatal_error("G?"); - AliasedG = M->getNamedAlias("g_alias"); - if (!AliasedG) - report_fatal_error("AliasedG?"); - - MachineModuleInfo MMI(TM.get()); - - MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), - MMI.getContext(), 0); - - DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); - if (!DAG) - report_fatal_error("DAG?"); - OptimizationRemarkEmitter ORE(F); - FunctionAnalysisManager FAM; - FAM.registerPass([&] { return TM->getTargetIRAnalysis(); }); - - TargetTransformInfo TTI = TM->getTargetIRAnalysis().run(*F, FAM); - DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI, - nullptr, TTI.hasBranchDivergence(F)); - } - - TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { - return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); - } - - EVT getTypeToTransformTo(EVT VT) { - return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); - } - - LLVMContext Context; - std::unique_ptr<TargetMachine> TM; - std::unique_ptr<Module> M; - Function *F; - GlobalVariable *G; - GlobalAlias *AliasedG; - std::unique_ptr<MachineFunction> MF; - std::unique_ptr<SelectionDAG> DAG; -}; +class SelectionDAGPatternMatchTest : public SelectionDAGTestBase {}; TEST_F(SelectionDAGPatternMatchTest, matchValueType) { SDLoc DL; diff --git a/llvm/unittests/CodeGen/SelectionDAGTestBase.h b/llvm/unittests/CodeGen/SelectionDAGTestBase.h new file mode 100644 index 0000000..edc730d --- /dev/null +++ b/llvm/unittests/CodeGen/SelectionDAGTestBase.h @@ -0,0 +1,99 @@ +//===---- llvm/unittest/CodeGen/SelectionDAGTestBase.h --------------------===// +// +// 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/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "gtest/gtest.h" + +using namespace llvm; + +class SelectionDAGTestBase : public testing::Test { +protected: + static void SetUpTestCase() { + InitializeAllTargets(); + InitializeAllTargetMCs(); + } + + void SetUp() override { + StringRef Assembly = "@g = global i32 0\n" + "@g_alias = alias i32, i32* @g\n" + "define i32 @f() {\n" + " %1 = load i32, i32* @g\n" + " ret i32 %1\n" + "}"; + + Triple TargetTriple("aarch64--"); + std::string Error; + const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); + // FIXME: These tests do not depend on AArch64 specifically, but we have to + // initialize a target. A skeleton Target for unittests would allow us to + // always run these tests. + if (!T) + GTEST_SKIP(); + + TargetOptions Options; + TM = std::unique_ptr<TargetMachine>( + T->createTargetMachine(TargetTriple, "", "+sve", Options, std::nullopt, + std::nullopt, CodeGenOptLevel::Aggressive)); + if (!TM) + GTEST_SKIP(); + + SMDiagnostic SMError; + M = parseAssemblyString(Assembly, SMError, Context); + ASSERT_TRUE(M && "Could not parse module!"); + M->setDataLayout(TM->createDataLayout()); + + F = M->getFunction("f"); + ASSERT_TRUE(F && "Could not get function f!"); + G = M->getGlobalVariable("g"); + ASSERT_TRUE(G && "Could not get global g!"); + AliasedG = M->getNamedAlias("g_alias"); + ASSERT_TRUE(AliasedG && "Could not get alias g_alias!"); + + MachineModuleInfo MMI(TM.get()); + + MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F), + MMI.getContext(), 0); + + DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None); + if (!DAG) + reportFatalUsageError("Failed to create SelectionDAG?"); + OptimizationRemarkEmitter ORE(F); + FunctionAnalysisManager FAM; + FAM.registerPass([&] { return TM->getTargetIRAnalysis(); }); + + TargetTransformInfo TTI = TM->getTargetIRAnalysis().run(*F, FAM); + DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI, + nullptr, TTI.hasBranchDivergence(F)); + } + + TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) { + return DAG->getTargetLoweringInfo().getTypeAction(Context, VT); + } + + EVT getTypeToTransformTo(EVT VT) { + return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT); + } + + LLVMContext Context; + std::unique_ptr<TargetMachine> TM; + std::unique_ptr<Module> M; + Function *F; + GlobalVariable *G; + GlobalAlias *AliasedG; + std::unique_ptr<MachineFunction> MF; + std::unique_ptr<SelectionDAG> DAG; +}; diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 4a05a29..ec94083 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -1559,16 +1559,11 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) { #if LLVM_ENABLE_THREADS std::mutex WorkThreadsMutex; - std::vector<std::thread> WorkThreads; + SmallVector<std::thread, 0> WorkThreads; DispatchOverride = [&](std::unique_ptr<Task> T) { - std::promise<void> WaitP; std::lock_guard<std::mutex> Lock(WorkThreadsMutex); WorkThreads.push_back( - std::thread([T = std::move(T), WaitF = WaitP.get_future()]() mutable { - WaitF.get(); - T->run(); - })); - WaitP.set_value(); + std::thread([T = std::move(T)]() mutable { T->run(); })); }; cantFail(JD.define(absoluteSymbols({{Foo, FooSym}}))); @@ -1580,8 +1575,15 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) { EXPECT_EQ(FooLookupResult.getFlags(), FooSym.getFlags()) << "lookup returned incorrect flags"; - for (auto &WT : WorkThreads) + std::unique_lock<std::mutex> Lock(WorkThreadsMutex); + // This works because every child thread that is allowed to use WorkThreads + // must either be in WorkThreads or its parent must be in WorkThreads. + while (!WorkThreads.empty()) { + auto WT = WorkThreads.pop_back_val(); + Lock.unlock(); WT.join(); + Lock.lock(); + } #endif } diff --git a/llvm/unittests/ExecutionEngine/Orc/MemoryMapperTest.cpp b/llvm/unittests/ExecutionEngine/Orc/MemoryMapperTest.cpp index 6ab659d..fea9eab 100644 --- a/llvm/unittests/ExecutionEngine/Orc/MemoryMapperTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/MemoryMapperTest.cpp @@ -81,7 +81,7 @@ TEST(MemoryMapperTest, InitializeDeinitialize) { { // Provide working memory char *WA1 = Mapper->prepare(Mem1->Start, HW.size() + 1); - std::strcpy(static_cast<char *>(WA1), HW.c_str()); + std::strcpy(WA1, HW.c_str()); } // A structure to be passed to initialize @@ -106,7 +106,7 @@ TEST(MemoryMapperTest, InitializeDeinitialize) { { char *WA2 = Mapper->prepare(Mem1->Start + PageSize, HW.size() + 1); - std::strcpy(static_cast<char *>(WA2), HW.c_str()); + std::strcpy(WA2, HW.c_str()); } MemoryMapper::AllocInfo Alloc2; @@ -159,7 +159,7 @@ TEST(MemoryMapperTest, InitializeDeinitialize) { EXPECT_THAT_ERROR(Mem2.takeError(), Succeeded()); char *WA = Mapper->prepare(Mem2->Start, HW.size() + 1); - std::strcpy(static_cast<char *>(WA), HW.c_str()); + std::strcpy(WA, HW.c_str()); MemoryMapper::AllocInfo Alloc3; { diff --git a/llvm/unittests/Frontend/CMakeLists.txt b/llvm/unittests/Frontend/CMakeLists.txt index 281d509..6e4ba5d 100644 --- a/llvm/unittests/Frontend/CMakeLists.txt +++ b/llvm/unittests/Frontend/CMakeLists.txt @@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_unittest(LLVMFrontendTests + HLSLBindingTest.cpp HLSLRootSignatureDumpTest.cpp HLSLRootSignatureRangesTest.cpp OpenACCTest.cpp diff --git a/llvm/unittests/Frontend/HLSLBindingTest.cpp b/llvm/unittests/Frontend/HLSLBindingTest.cpp new file mode 100644 index 0000000..bd6a0ff --- /dev/null +++ b/llvm/unittests/Frontend/HLSLBindingTest.cpp @@ -0,0 +1,273 @@ +//===------ HLSLBindingTest.cpp - Resource binding 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/Frontend/HLSL/HLSLBinding.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DXILABI.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::dxil; + +MATCHER_P(HasSpecificValue, Value, "") { + return arg.has_value() && *arg == Value; +} + +static void +checkExpectedSpaceAndFreeRanges(hlsl::BindingInfo::RegisterSpace &RegSpace, + uint32_t ExpSpace, + ArrayRef<uint32_t> ExpValues) { + EXPECT_EQ(RegSpace.Space, ExpSpace); + EXPECT_EQ(RegSpace.FreeRanges.size() * 2, ExpValues.size()); + unsigned I = 0; + for (auto &R : RegSpace.FreeRanges) { + EXPECT_EQ(R.LowerBound, ExpValues[I]); + EXPECT_EQ(R.UpperBound, ExpValues[I + 1]); + I += 2; + } +} + +TEST(HLSLBindingTest, TestTrivialCase) { + hlsl::BindingInfoBuilder Builder; + + Builder.trackBinding(ResourceClass::UAV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/nullptr); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_FALSE(HasOverlap); + + // check that UAV has exactly one gap + hlsl::BindingInfo::BindingSpaces &UAVSpaces = + Info.getBindingSpaces(ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.Spaces.size(), 1u); + checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, {0u, 4u, 6u, ~0u}); + + // check that other kinds of register spaces are all available + for (auto RC : + {ResourceClass::SRV, ResourceClass::CBuffer, ResourceClass::Sampler}) { + hlsl::BindingInfo::BindingSpaces &Spaces = Info.getBindingSpaces(RC); + EXPECT_EQ(Spaces.RC, RC); + EXPECT_EQ(Spaces.Spaces.size(), 0u); + } +} + +TEST(HLSLBindingTest, TestManyBindings) { + hlsl::BindingInfoBuilder Builder; + + // cbuffer CB : register(b3) { int a; } + // RWBuffer<float4> A[5] : register(u10, space20); + // StructuredBuffer<int> B : register(t5); + // RWBuffer<float> C : register(u5); + // StructuredBuffer<int> D[5] : register(t0); + // RWBuffer<float> E[2] : register(u2); + // SamplerState S1 : register(s5, space2); + // SamplerState S2 : register(s4, space2); + Builder.trackBinding(ResourceClass::CBuffer, /*Space=*/0, /*LowerBound=*/3, + /*UpperBound=*/3, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/20, /*LowerBound=*/10, + /*UpperBound=*/14, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/0, + /*UpperBound=*/4, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/0, /*LowerBound=*/2, + /*UpperBound=*/3, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::Sampler, /*Space=*/2, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::Sampler, /*Space=*/2, /*LowerBound=*/4, + /*UpperBound=*/4, /*Cookie=*/nullptr); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_FALSE(HasOverlap); + + hlsl::BindingInfo::BindingSpaces &SRVSpaces = + Info.getBindingSpaces(ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.Spaces.size(), 1u); + // verify that consecutive bindings are merged + // (SRVSpaces has only one free space range {6, ~0u}). + checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {6u, ~0u}); + + hlsl::BindingInfo::BindingSpaces &UAVSpaces = + Info.getBindingSpaces(ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.Spaces.size(), 2u); + checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, + {0u, 1u, 4u, 4u, 6u, ~0u}); + checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[1], 20, {0u, 9u, 15u, ~0u}); + + hlsl::BindingInfo::BindingSpaces &CBufferSpaces = + Info.getBindingSpaces(ResourceClass::CBuffer); + EXPECT_EQ(CBufferSpaces.RC, ResourceClass::CBuffer); + EXPECT_EQ(CBufferSpaces.Spaces.size(), 1u); + checkExpectedSpaceAndFreeRanges(CBufferSpaces.Spaces[0], 0, + {0u, 2u, 4u, ~0u}); + + hlsl::BindingInfo::BindingSpaces &SamplerSpaces = + Info.getBindingSpaces(ResourceClass::Sampler); + EXPECT_EQ(SamplerSpaces.RC, ResourceClass::Sampler); + EXPECT_EQ(SamplerSpaces.Spaces.size(), 1u); + checkExpectedSpaceAndFreeRanges(SamplerSpaces.Spaces[0], 2, + {0u, 3u, 6u, ~0u}); +} + +TEST(HLSLBindingTest, TestUnboundedAndOverlap) { + hlsl::BindingInfoBuilder Builder; + + // StructuredBuffer<float> A[] : register(t5); + // StructuredBuffer<float> B[3] : register(t0); + // StructuredBuffer<float> C[] : register(t0, space2); + // StructuredBuffer<float> D : register(t4, space2); /* overlapping */ + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/~0u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/0, + /*UpperBound=*/2, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/2, /*LowerBound=*/0, + /*UpperBound=*/~0u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/2, /*LowerBound=*/4, + /*UpperBound=*/4, /*Cookie=*/nullptr); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_TRUE(HasOverlap); + + hlsl::BindingInfo::BindingSpaces &SRVSpaces = + Info.getBindingSpaces(ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.Spaces.size(), 2u); + checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {3, 4}); + checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[1], 2, {}); +} + +TEST(HLSLBindingTest, TestExactOverlap) { + hlsl::BindingInfoBuilder Builder; + + // Since the bindings overlap exactly we need sigil values to differentiate + // them. + char ID1; + char ID2; + + // StructuredBuffer<float> A : register(t5); + // StructuredBuffer<float> B : register(t5); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/&ID1); + Builder.trackBinding(ResourceClass::SRV, /*Space=*/0, /*LowerBound=*/5, + /*UpperBound=*/5, /*Cookie=*/&ID2); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_TRUE(HasOverlap); + + hlsl::BindingInfo::BindingSpaces &SRVSpaces = + Info.getBindingSpaces(ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); + EXPECT_EQ(SRVSpaces.Spaces.size(), 1u); + checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {0u, 4u, 6u, ~0u}); +} + +TEST(HLSLBindingTest, TestEndOfRange) { + hlsl::BindingInfoBuilder Builder; + + // RWBuffer<float> A : register(u4294967295); /* UINT32_MAX */ + // RWBuffer<float> B[10] : register(u4294967286, space1); + // /* range (UINT32_MAX - 9, UINT32_MAX )*/ + // RWBuffer<float> C[10] : register(u2147483647, space2); + // /* range (INT32_MAX, INT32_MAX + 9) */ + Builder.trackBinding(ResourceClass::UAV, /*Space=*/0, /*LowerBound=*/~0u, + /*UpperBound=*/~0u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/1, /*LowerBound=*/~0u - 9u, + /*UpperBound=*/~0u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/2, + /*LowerBound=*/2147483647u, + /*UpperBound=*/2147483647u + 9u, /*Cookie=*/nullptr); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_FALSE(HasOverlap); + + hlsl::BindingInfo::BindingSpaces &UAVSpaces = + Info.getBindingSpaces(ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); + EXPECT_EQ(UAVSpaces.Spaces.size(), 3u); + checkExpectedSpaceAndFreeRanges( + UAVSpaces.Spaces[0], 0, {0, std::numeric_limits<uint32_t>::max() - 1}); + checkExpectedSpaceAndFreeRanges( + UAVSpaces.Spaces[1], 1, {0, std::numeric_limits<uint32_t>::max() - 10}); + checkExpectedSpaceAndFreeRanges( + UAVSpaces.Spaces[2], 2, + {0, static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) - 1u, + static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) + 10u, + std::numeric_limits<uint32_t>::max()}); +} + +TEST(HLSLBindingTest, TestFindAvailable) { + hlsl::BindingInfoBuilder Builder; + + // RWBuffer<float> A : register(u5); + // RWBuffer<float> B : register(u5, space1); + // RWBuffer<float> C : register(u11, space1); + // RWBuffer<float> D[] : register(u1, space2); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/0, /*LowerBound=*/5u, + /*UpperBound=*/5u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/1, /*LowerBound=*/2u, + /*UpperBound=*/2u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/1, /*LowerBound=*/6u, + /*UpperBound=*/6u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/2, /*LowerBound=*/1u, + /*UpperBound=*/~0u, /*Cookie=*/nullptr); + Builder.trackBinding(ResourceClass::UAV, /*Space=*/3, /*LowerBound=*/~0u - 1, + /*UpperBound=*/~0u - 1, /*Cookie=*/nullptr); + bool HasOverlap; + hlsl::BindingInfo Info = Builder.calculateBindingInfo(HasOverlap); + + EXPECT_FALSE(HasOverlap); + + // In space 0, we find room for a small binding at the beginning and + // a large binding after `A`'s binding. + std::optional<uint32_t> V = + Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/0, /*Size=*/1); + EXPECT_THAT(V, HasSpecificValue(0u)); + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/0, /*Size=*/100); + EXPECT_THAT(V, HasSpecificValue(6u)); + + // In space 1, we try to fit larger bindings in the fill the gaps. Note that + // we do this largest to smallest and observe that the gaps that are earlier + // still exist. + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/1, /*Size=*/4); + EXPECT_THAT(V, HasSpecificValue(7u)); + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/1, /*Size=*/3); + EXPECT_THAT(V, HasSpecificValue(3u)); + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/1, /*Size=*/2); + EXPECT_THAT(V, HasSpecificValue(0u)); + // At this point, we've used all of the contiguous space up to 11u + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/1, /*Size=*/1); + EXPECT_THAT(V, HasSpecificValue(11u)); + + // Space 2 is mostly full, we can only fit into the room at the beginning. + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/2, /*Size=*/2); + EXPECT_FALSE(V.has_value()); + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/2, /*Size=*/1); + EXPECT_THAT(V, HasSpecificValue(0u)); + + // Finding space for an unbounded array is a bit funnier. it always needs to + // go a the end of the available space. + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/3, + /*Size=*/~0u); + // Note that we end up with a size 1 array here, starting at ~0u. + EXPECT_THAT(V, HasSpecificValue(~0u)); + V = Info.findAvailableBinding(ResourceClass::UAV, /*Space=*/4, + /*Size=*/~0u); + // In an empty space we find the slot at the beginning. + EXPECT_THAT(V, HasSpecificValue(0u)); +} diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp index 22dffd8..0c464c1 100644 --- a/llvm/unittests/Support/DebugLogTest.cpp +++ b/llvm/unittests/Support/DebugLogTest.cpp @@ -6,7 +6,13 @@ // //===----------------------------------------------------------------------===// +// This macro is defined in the LLVM build system, but we undefine it here +// so that we test at least once in-tree the case where __SHORT_FILE__ is not +// defined. +#undef __SHORT_FILE__ + #include "llvm/Support/DebugLog.h" +#include "llvm/ADT/Sequence.h" #include "llvm/Support/raw_ostream.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -26,8 +32,8 @@ TEST(DebugLogTest, Basic) { { std::string str; raw_string_ostream os(str); - DEBUGLOG_WITH_STREAM_AND_TYPE(os, nullptr) << "NoType"; - EXPECT_TRUE(StringRef(os.str()).starts_with('[')); + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, nullptr) << "NoType"; + EXPECT_FALSE(StringRef(os.str()).starts_with('[')); EXPECT_TRUE(StringRef(os.str()).ends_with("NoType\n")); } @@ -35,8 +41,9 @@ TEST(DebugLogTest, Basic) { { std::string str; raw_string_ostream os(str); - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "A"; - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "B") << "B"; + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "A") << "A"; + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "B") << "B"; + EXPECT_TRUE(StringRef(os.str()).starts_with('[')); EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n"))); } @@ -46,21 +53,76 @@ TEST(DebugLogTest, Basic) { raw_string_ostream os(str); // Just check that the macro doesn't result in dangling else. if (true) - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "A"; + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "A") << "A"; else - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "B"; - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "B") << "B"; + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "A") << "B"; + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "B") << "B"; EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), Not(HasSubstr("B\n")))); int count = 0; auto inc = [&]() { return ++count; }; EXPECT_THAT(count, Eq(0)); - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << inc(); + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "A") << inc(); EXPECT_THAT(count, Eq(1)); - DEBUGLOG_WITH_STREAM_AND_TYPE(os, "B") << inc(); + DEBUGLOG_WITH_STREAM_AND_TYPE(os, 0, "B") << inc(); EXPECT_THAT(count, Eq(1)); } } + +TEST(DebugLogTest, BasicWithLevel) { + llvm::DebugFlag = true; + // We expect A to be always printed, B to be printed only when level is 1 or + // below, and C to be printed only when level is 0 or below. + static const char *DT[] = {"A", "B:1", "C:"}; + + setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0])); + std::string str; + raw_string_ostream os(str); + for (auto type : {"A", "B", "C", "D"}) + for (int level : llvm::seq<int>(0, 4)) + DEBUGLOG_WITH_STREAM_TYPE_FILE_AND_LINE(os, level, type, type, level) + << level; + EXPECT_EQ(os.str(), "[A:0] A:0 0\n[A:1] A:1 1\n[A:2] A:2 2\n[A:3] A:3 " + "3\n[B:0] B:0 0\n[B:1] B:1 1\n[C:0] C:0 0\n"); +} + +TEST(DebugLogTest, NegativeLevel) { + llvm::DebugFlag = true; + // Test the special behavior when all the levels are 0. + // In this case we expect all the debug types to be printed. + static const char *DT[] = {"A:"}; + + setCurrentDebugTypes(DT, sizeof(DT) / sizeof(DT[0])); + std::string str; + raw_string_ostream os(str); + for (auto type : {"A", "B"}) + for (int level : llvm::seq<int>(0, 2)) + DEBUGLOG_WITH_STREAM_TYPE_FILE_AND_LINE(os, level, type, type, level) + << level; + EXPECT_EQ(os.str(), "[A:0] A:0 0\n[B:0] B:0 0\n[B:1] B:1 1\n"); +} + +TEST(DebugLogTest, StreamPrefix) { + llvm::DebugFlag = true; + static const char *DT[] = {"A", "B"}; + setCurrentDebugTypes(DT, 2); + + std::string str; + raw_string_ostream os(str); + std::string expected = "PrefixA 1\nPrefixA 2\nPrefixA \nPrefixB " + "3\nPrefixB 4\nPrefixA 5"; + { + llvm::impl::raw_ldbg_ostream ldbg_osB("PrefixB ", os); + llvm::impl::raw_ldbg_ostream ldbg_osA("PrefixA ", os); + ldbg_osA << "1\n2"; + ldbg_osA << "\n\n"; + ldbg_osB << "3\n4\n"; + ldbg_osA << "5"; + EXPECT_EQ(os.str(), expected); + } + // After destructors, there was a pending newline for stream B. + EXPECT_EQ(os.str(), expected + "\nPrefixB \n"); +} #else TEST(DebugLogTest, Basic) { // LDBG should be compiled out in NDEBUG, so just check it compiles and has diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index eb590e4..fc3ccea 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -225,7 +225,7 @@ std::string getPosixPath(const Twine &S) { } // end anonymous namespace TEST(VirtualFileSystemTest, StatusQueries) { - IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); + auto D = makeIntrusiveRefCnt<DummyFileSystem>(); ErrorOr<vfs::Status> Status((std::error_code())); D->addRegularFile("/foo"); @@ -265,11 +265,11 @@ TEST(VirtualFileSystemTest, StatusQueries) { } TEST(VirtualFileSystemTest, BaseOnlyOverlay) { - IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem()); + auto D = makeIntrusiveRefCnt<DummyFileSystem>(); ErrorOr<vfs::Status> Status((std::error_code())); EXPECT_FALSE(Status = D->status("/foo")); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(D); EXPECT_FALSE(Status = O->status("/foo")); D->addRegularFile("/foo"); @@ -283,13 +283,12 @@ TEST(VirtualFileSystemTest, BaseOnlyOverlay) { } TEST(VirtualFileSystemTest, GetRealPathInOverlay) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("/foo"); Lower->addSymlink("/lower_link"); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); // Regular file. @@ -312,11 +311,10 @@ TEST(VirtualFileSystemTest, GetRealPathInOverlay) { } TEST(VirtualFileSystemTest, OverlayFiles) { - IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Base)); + auto Base = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Middle = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Top = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Base); O->pushOverlay(Middle); O->pushOverlay(Top); @@ -351,10 +349,9 @@ TEST(VirtualFileSystemTest, OverlayFiles) { } TEST(VirtualFileSystemTest, OverlayDirsNonMerged) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); Lower->addDirectory("/lower-only"); @@ -376,10 +373,9 @@ TEST(VirtualFileSystemTest, OverlayDirsNonMerged) { TEST(VirtualFileSystemTest, MergedDirPermissions) { // merged directories get the permissions of the upper dir - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); ErrorOr<vfs::Status> Status((std::error_code())); @@ -401,12 +397,11 @@ TEST(VirtualFileSystemTest, MergedDirPermissions) { } TEST(VirtualFileSystemTest, OverlayIterator) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("/foo"); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); ErrorOr<vfs::Status> Status((std::error_code())); @@ -784,10 +779,9 @@ static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) { } TEST(VirtualFileSystemTest, OverlayIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); std::error_code EC; @@ -808,11 +802,10 @@ TEST(VirtualFileSystemTest, OverlayIteration) { } TEST(VirtualFileSystemTest, OverlayRecursiveIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Middle = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Middle); O->pushOverlay(Upper); @@ -850,11 +843,10 @@ TEST(VirtualFileSystemTest, OverlayRecursiveIteration) { } TEST(VirtualFileSystemTest, ThreeLevelIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Middle = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Middle); O->pushOverlay(Upper); @@ -870,11 +862,10 @@ TEST(VirtualFileSystemTest, ThreeLevelIteration) { } TEST(VirtualFileSystemTest, HiddenInIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Middle = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Middle); O->pushOverlay(Upper); @@ -913,11 +904,10 @@ TEST(VirtualFileSystemTest, HiddenInIteration) { } TEST(VirtualFileSystemTest, Visit) { - IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Base)); + auto Base = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Middle = makeIntrusiveRefCnt<DummyFileSystem>(); + auto Top = makeIntrusiveRefCnt<DummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Base); O->pushOverlay(Middle); O->pushOverlay(Top); @@ -984,10 +974,9 @@ TEST(OverlayFileSystemTest, PrintOutput) { } TEST(OverlayFileSystemTest, Exists) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new NoStatusDummyFileSystem()); - IntrusiveRefCntPtr<DummyFileSystem> Upper(new NoStatusDummyFileSystem()); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto Lower = makeIntrusiveRefCnt<NoStatusDummyFileSystem>(); + auto Upper = makeIntrusiveRefCnt<NoStatusDummyFileSystem>(); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(Upper); Lower->addDirectory("/both"); @@ -1008,8 +997,7 @@ TEST(OverlayFileSystemTest, Exists) { } TEST(ProxyFileSystemTest, Basic) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> Base( - new vfs::InMemoryFileSystem()); + auto Base = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); vfs::ProxyFileSystem PFS(Base); Base->addFile("/a", 0, MemoryBuffer::getMemBuffer("test")); @@ -1606,7 +1594,7 @@ TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) { } TEST_F(VFSFromYAMLTest, MappedFiles) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo/bar"); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( @@ -1642,8 +1630,7 @@ TEST_F(VFSFromYAMLTest, MappedFiles) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); // file @@ -1720,7 +1707,7 @@ TEST_F(VFSFromYAMLTest, MappedFiles) { } TEST_F(VFSFromYAMLTest, MappedRoot) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo/bar"); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = @@ -1735,8 +1722,7 @@ TEST_F(VFSFromYAMLTest, MappedRoot) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); // file @@ -1762,7 +1748,7 @@ TEST_F(VFSFromYAMLTest, MappedRoot) { } TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlay) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); Lower->addDirectory("//root/bar"); @@ -1783,8 +1769,7 @@ TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlay) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); ErrorOr<vfs::Status> S = O->status("//root/foo"); @@ -1806,7 +1791,7 @@ TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlay) { } TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlayNoExternalNames) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); Lower->addDirectory("//root/bar"); @@ -1847,7 +1832,7 @@ TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlayNoExternalNames) { } TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlayNoFallthrough) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); Lower->addDirectory("//root/bar"); @@ -1887,13 +1872,12 @@ TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlayNoFallthrough) { } TEST_F(VFSFromYAMLTest, ReturnsRequestedPathVFSMiss) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS( - new vfs::InMemoryFileSystem); + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/foo/a", 0, MemoryBuffer::getMemBuffer("contents of a")); ASSERT_FALSE(BaseFS->setCurrentWorkingDirectory("//root/foo")); auto RemappedFS = vfs::RedirectingFileSystem::create( - {}, /*UseExternalNames=*/false, *BaseFS); + {}, /*UseExternalNames=*/false, BaseFS); auto OpenedF = RemappedFS->openFileForRead("a"); ASSERT_FALSE(OpenedF.getError()); @@ -1915,8 +1899,7 @@ TEST_F(VFSFromYAMLTest, ReturnsRequestedPathVFSMiss) { } TEST_F(VFSFromYAMLTest, ReturnsExternalPathVFSHit) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS( - new vfs::InMemoryFileSystem); + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/foo/realname", 0, MemoryBuffer::getMemBuffer("contents of a")); auto FS = @@ -1955,7 +1938,7 @@ TEST_F(VFSFromYAMLTest, ReturnsExternalPathVFSHit) { } TEST_F(VFSFromYAMLTest, RootRelativeTest) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/foo/bar"); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = @@ -1996,7 +1979,7 @@ TEST_F(VFSFromYAMLTest, RootRelativeTest) { ASSERT_FALSE(S.getError()); EXPECT_EQ("//root/foo/bar/a", S->getName()); #else - IntrusiveRefCntPtr<DummyFileSystem> LowerWindows(new DummyFileSystem()); + auto LowerWindows = makeIntrusiveRefCnt<DummyFileSystem>(); LowerWindows->addDirectory("\\\\root\\foo\\bar"); LowerWindows->addRegularFile("\\\\root\\foo\\bar\\a"); FS = getFromYAMLString("{\n" @@ -2018,8 +2001,7 @@ TEST_F(VFSFromYAMLTest, RootRelativeTest) { } TEST_F(VFSFromYAMLTest, ReturnsInternalPathVFSHit) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS( - new vfs::InMemoryFileSystem); + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/foo/realname", 0, MemoryBuffer::getMemBuffer("contents of a")); auto FS = @@ -2058,7 +2040,7 @@ TEST_F(VFSFromYAMLTest, ReturnsInternalPathVFSHit) { } TEST_F(VFSFromYAMLTest, CaseInsensitive) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( "{ 'case-sensitive': 'false',\n" @@ -2076,8 +2058,7 @@ TEST_F(VFSFromYAMLTest, CaseInsensitive) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); ErrorOr<vfs::Status> S = O->status("//root/XX"); @@ -2094,7 +2075,7 @@ TEST_F(VFSFromYAMLTest, CaseInsensitive) { } TEST_F(VFSFromYAMLTest, CaseSensitive) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( "{ 'case-sensitive': 'true',\n" @@ -2112,8 +2093,7 @@ TEST_F(VFSFromYAMLTest, CaseSensitive) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); ErrorOr<vfs::Status> SS = O->status("//root/xx"); @@ -2126,7 +2106,7 @@ TEST_F(VFSFromYAMLTest, CaseSensitive) { } TEST_F(VFSFromYAMLTest, IllegalVFSFile) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); // invalid YAML at top-level IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower); @@ -2252,7 +2232,7 @@ TEST_F(VFSFromYAMLTest, IllegalVFSFile) { } TEST_F(VFSFromYAMLTest, UseExternalName) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("//root/external/file"); IntrusiveRefCntPtr<vfs::FileSystem> FS = @@ -2304,7 +2284,7 @@ TEST_F(VFSFromYAMLTest, UseExternalName) { } TEST_F(VFSFromYAMLTest, MultiComponentPath) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("//root/other"); // file in roots @@ -2350,7 +2330,7 @@ TEST_F(VFSFromYAMLTest, MultiComponentPath) { } TEST_F(VFSFromYAMLTest, TrailingSlashes) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addRegularFile("//root/other"); // file in roots @@ -2369,7 +2349,7 @@ TEST_F(VFSFromYAMLTest, TrailingSlashes) { } TEST_F(VFSFromYAMLTest, DirectoryIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addDirectory("//root/foo/bar"); @@ -2399,8 +2379,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); std::error_code EC; @@ -2416,7 +2395,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) { if (!supportsSameDirMultipleYAMLEntries()) GTEST_SKIP(); - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/zab"); Lower->addDirectory("//root/baz"); Lower->addRegularFile("//root/zab/a"); @@ -2449,8 +2428,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); std::error_code EC; @@ -2461,7 +2439,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) { TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/a"); Lower->addDirectory("//root/a/b"); Lower->addDirectory("//root/a/b/c"); @@ -2484,8 +2462,7 @@ TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { Lower); ASSERT_NE(FS.get(), nullptr); - IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( - new vfs::OverlayFileSystem(Lower)); + auto O = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Lower); O->pushOverlay(FS); std::error_code EC; @@ -2503,7 +2480,7 @@ TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { } TEST_F(VFSFromYAMLTest, RelativePaths) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); std::error_code EC; SmallString<128> CWD; EC = llvm::sys::fs::current_path(CWD); @@ -2557,7 +2534,7 @@ TEST_F(VFSFromYAMLTest, RelativePaths) { } TEST_F(VFSFromYAMLTest, NonFallthroughDirectoryIteration) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addRegularFile("//root/a"); Lower->addRegularFile("//root/b"); @@ -2586,7 +2563,7 @@ TEST_F(VFSFromYAMLTest, NonFallthroughDirectoryIteration) { } TEST_F(VFSFromYAMLTest, DirectoryIterationWithDuplicates) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addRegularFile("//root/a"); Lower->addRegularFile("//root/b"); @@ -2614,7 +2591,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationWithDuplicates) { } TEST_F(VFSFromYAMLTest, DirectoryIterationErrorInVFSLayer) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); @@ -2643,7 +2620,7 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationErrorInVFSLayer) { } TEST_F(VFSFromYAMLTest, GetRealPath) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//dir/"); Lower->addRegularFile("/foo"); Lower->addSymlink("/link"); @@ -2695,7 +2672,7 @@ TEST_F(VFSFromYAMLTest, GetRealPath) { } TEST_F(VFSFromYAMLTest, WorkingDirectory) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); @@ -2753,7 +2730,7 @@ TEST_F(VFSFromYAMLTest, WorkingDirectory) { } TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthrough) { - IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<DummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); @@ -2835,7 +2812,7 @@ TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthrough) { } TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) { - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); @@ -2872,7 +2849,7 @@ TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) { } TEST_F(VFSFromYAMLTest, VirtualWorkingDirectory) { - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addRegularFile("//root/foo/a"); @@ -2928,7 +2905,7 @@ TEST_F(VFSFromYAMLTest, YAMLVFSWriterTest) { raw_string_ostream OS(Buffer); VFSWriter.write(OS); - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); Lower->addDirectory("//root/"); Lower->addDirectory("//root/a"); Lower->addRegularFile("//root/a/b"); @@ -2978,7 +2955,7 @@ TEST_F(VFSFromYAMLTest, YAMLVFSWriterTest2) { raw_string_ostream OS(Buffer); VFSWriter.write(OS); - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLRawString(Buffer, Lower); EXPECT_NE(FS.get(), nullptr); } @@ -3010,7 +2987,7 @@ TEST_F(VFSFromYAMLTest, YAMLVFSWriterTest3) { raw_string_ostream OS(Buffer); VFSWriter.write(OS); - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLRawString(Buffer, Lower); EXPECT_NE(FS.get(), nullptr); } @@ -3033,7 +3010,7 @@ TEST_F(VFSFromYAMLTest, YAMLVFSWriterTestHandleDirs) { // We didn't add a single file - only directories. EXPECT_EQ(Buffer.find("'type': 'file'"), std::string::npos); - IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem()); + auto Lower = makeIntrusiveRefCnt<ErrorDummyFileSystem>(); Lower->addDirectory("//root/a"); Lower->addDirectory("//root/b"); Lower->addDirectory("//root/c"); @@ -3051,17 +3028,17 @@ TEST_F(VFSFromYAMLTest, YAMLVFSWriterTestHandleDirs) { } TEST_F(VFSFromYAMLTest, RedirectingWith) { - IntrusiveRefCntPtr<DummyFileSystem> Both(new DummyFileSystem()); + auto Both = makeIntrusiveRefCnt<DummyFileSystem>(); Both->addDirectory("//root/a"); Both->addRegularFile("//root/a/f"); Both->addDirectory("//root/b"); Both->addRegularFile("//root/b/f"); - IntrusiveRefCntPtr<DummyFileSystem> AOnly(new DummyFileSystem()); + auto AOnly = makeIntrusiveRefCnt<DummyFileSystem>(); AOnly->addDirectory("//root/a"); AOnly->addRegularFile("//root/a/f"); - IntrusiveRefCntPtr<DummyFileSystem> BOnly(new DummyFileSystem()); + auto BOnly = makeIntrusiveRefCnt<DummyFileSystem>(); BOnly->addDirectory("//root/b"); BOnly->addRegularFile("//root/b/f"); @@ -3166,8 +3143,7 @@ TEST_F(VFSFromYAMLTest, RedirectingWith) { } TEST(VFSFromRemappedFilesTest, Basic) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS = - new vfs::InMemoryFileSystem; + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b")); BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c")); @@ -3176,7 +3152,7 @@ TEST(VFSFromRemappedFilesTest, Basic) { {"//root/a/b/c", "//root/c"}, }; auto RemappedFS = vfs::RedirectingFileSystem::create( - RemappedFiles, /*UseExternalNames=*/false, *BaseFS); + RemappedFiles, /*UseExternalNames=*/false, BaseFS); auto StatA = RemappedFS->status("//root/a/a"); auto StatB = RemappedFS->status("//root/a/b/c"); @@ -3194,8 +3170,7 @@ TEST(VFSFromRemappedFilesTest, Basic) { } TEST(VFSFromRemappedFilesTest, UseExternalNames) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS = - new vfs::InMemoryFileSystem; + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b")); BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c")); @@ -3204,7 +3179,7 @@ TEST(VFSFromRemappedFilesTest, UseExternalNames) { {"//root/a/b/c", "//root/c"}, }; auto RemappedFS = vfs::RedirectingFileSystem::create( - RemappedFiles, /*UseExternalNames=*/true, *BaseFS); + RemappedFiles, /*UseExternalNames=*/true, BaseFS); auto StatA = RemappedFS->status("//root/a/a"); auto StatB = RemappedFS->status("//root/a/b/c"); @@ -3222,8 +3197,7 @@ TEST(VFSFromRemappedFilesTest, UseExternalNames) { } TEST(VFSFromRemappedFilesTest, LastMappingWins) { - IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS = - new vfs::InMemoryFileSystem; + auto BaseFS = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>(); BaseFS->addFile("//root/b", 0, MemoryBuffer::getMemBuffer("contents of b")); BaseFS->addFile("//root/c", 0, MemoryBuffer::getMemBuffer("contents of c")); @@ -3232,9 +3206,9 @@ TEST(VFSFromRemappedFilesTest, LastMappingWins) { {"//root/a", "//root/c"}, }; auto RemappedFSKeepName = vfs::RedirectingFileSystem::create( - RemappedFiles, /*UseExternalNames=*/false, *BaseFS); + RemappedFiles, /*UseExternalNames=*/false, BaseFS); auto RemappedFSExternalName = vfs::RedirectingFileSystem::create( - RemappedFiles, /*UseExternalNames=*/true, *BaseFS); + RemappedFiles, /*UseExternalNames=*/true, BaseFS); auto StatKeepA = RemappedFSKeepName->status("//root/a"); auto StatExternalA = RemappedFSExternalName->status("//root/a"); @@ -3416,7 +3390,7 @@ TEST(RedirectingFileSystemTest, ExternalPaths) { BaseFS->setCurrentWorkingDirectory("/cwd"); auto CheckFS = makeIntrusiveRefCnt<InterceptorFS>(BaseFS); auto FS = vfs::RedirectingFileSystem::create({}, /*UseExternalNames=*/false, - *CheckFS); + CheckFS); FS->status("/a/../b"); FS->openFileForRead("c"); @@ -3442,7 +3416,7 @@ TEST(RedirectingFileSystemTest, ExternalPaths) { } TEST(RedirectingFileSystemTest, Exists) { - IntrusiveRefCntPtr<DummyFileSystem> Dummy(new NoStatusDummyFileSystem()); + auto Dummy = makeIntrusiveRefCnt<NoStatusDummyFileSystem>(); auto YAML = MemoryBuffer::getMemBuffer("{\n" " 'version': 0,\n" @@ -3513,7 +3487,7 @@ TEST(RedirectingFileSystemTest, Exists) { } TEST(RedirectingFileSystemTest, ExistsFallback) { - IntrusiveRefCntPtr<DummyFileSystem> Dummy(new NoStatusDummyFileSystem()); + auto Dummy = makeIntrusiveRefCnt<NoStatusDummyFileSystem>(); auto YAML = MemoryBuffer::getMemBuffer("{\n" " 'version': 0,\n" @@ -3537,7 +3511,7 @@ TEST(RedirectingFileSystemTest, ExistsFallback) { } TEST(RedirectingFileSystemTest, ExistsRedirectOnly) { - IntrusiveRefCntPtr<DummyFileSystem> Dummy(new NoStatusDummyFileSystem()); + auto Dummy = makeIntrusiveRefCnt<NoStatusDummyFileSystem>(); auto YAML = MemoryBuffer::getMemBuffer("{\n" " 'version': 0,\n" diff --git a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp index 6cd1a48..d4715be 100644 --- a/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp +++ b/llvm/unittests/Target/DirectX/ResourceBindingAnalysisTests.cpp @@ -44,19 +44,6 @@ protected: delete MAM; delete Context; } - - void checkExpectedSpaceAndFreeRanges( - DXILResourceBindingInfo::RegisterSpace &RegSpace, uint32_t ExpSpace, - ArrayRef<uint32_t> ExpValues) { - EXPECT_EQ(RegSpace.Space, ExpSpace); - EXPECT_EQ(RegSpace.FreeRanges.size() * 2, ExpValues.size()); - unsigned I = 0; - for (auto &R : RegSpace.FreeRanges) { - EXPECT_EQ(R.LowerBound, ExpValues[I]); - EXPECT_EQ(R.UpperBound, ExpValues[I + 1]); - I += 2; - } - } }; TEST_F(ResourceBindingAnalysisTest, TestTrivialCase) { @@ -76,103 +63,16 @@ entry: EXPECT_EQ(false, DRBI.hasImplicitBinding()); EXPECT_EQ(false, DRBI.hasOverlappingBinding()); - - // check that UAV has exactly one gap - DXILResourceBindingInfo::BindingSpaces &UAVSpaces = - DRBI.getBindingSpaces(ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.Spaces.size(), 1u); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, - {0, 4, 6, UINT32_MAX}); - - // check that other kinds of register spaces are all available - for (auto RC : - {ResourceClass::SRV, ResourceClass::CBuffer, ResourceClass::Sampler}) { - DXILResourceBindingInfo::BindingSpaces &Spaces = DRBI.getBindingSpaces(RC); - EXPECT_EQ(Spaces.RC, RC); - EXPECT_EQ(Spaces.Spaces.size(), 0u); - } -} - -TEST_F(ResourceBindingAnalysisTest, TestManyBindings) { - // cbuffer CB : register(b3) { int a; } - // RWBuffer<float4> A[5] : register(u10, space20); - // StructuredBuffer<int> B : register(t5); - // RWBuffer<float> C : register(u5); - // StructuredBuffer<int> D[5] : register(t0); - // RWBuffer<float> E[2] : register(u2); - // SamplerState S1 : register(s5, space2); - // SamplerState S2 : register(s4, space2); - StringRef Assembly = R"( -%__cblayout_CB = type <{ i32 }> -define void @main() { -entry: - %handleCB = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 0, i32 3, i32 1, i32 0, i1 false, ptr null) - %handleA = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 20, i32 10, i32 5, i32 0, i1 false, ptr null) - %handleB = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr null) - %handleC = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr null) - %handleD = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 5, i32 4, i1 false, ptr null) - %handleE = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 2, i32 0, i1 false, ptr null) - %handleS1 = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 5, i32 1, i32 0, i1 false, ptr null) - %handleS2 = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 4, i32 1, i32 0, i1 false, ptr null) - ; duplicate binding for the same resource - %handleD2 = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 5, i32 4, i1 false, ptr null) - ret void -} - )"; - - auto M = parseAsm(Assembly); - - DXILResourceBindingInfo &DRBI = - MAM->getResult<DXILResourceBindingAnalysis>(*M); - - EXPECT_EQ(false, DRBI.hasImplicitBinding()); - EXPECT_EQ(false, DRBI.hasOverlappingBinding()); - - DXILResourceBindingInfo::BindingSpaces &SRVSpaces = - DRBI.getBindingSpaces(ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.Spaces.size(), 1u); - // verify that consecutive bindings are merged - // (SRVSpaces has only one free space range {6, UINT32_MAX}). - checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {6, UINT32_MAX}); - - DXILResourceBindingInfo::BindingSpaces &UAVSpaces = - DRBI.getBindingSpaces(ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.Spaces.size(), 2u); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, - {0, 1, 4, 4, 6, UINT32_MAX}); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[1], 20, - {0, 9, 15, UINT32_MAX}); - - DXILResourceBindingInfo::BindingSpaces &CBufferSpaces = - DRBI.getBindingSpaces(ResourceClass::CBuffer); - EXPECT_EQ(CBufferSpaces.RC, ResourceClass::CBuffer); - EXPECT_EQ(CBufferSpaces.Spaces.size(), 1u); - checkExpectedSpaceAndFreeRanges(CBufferSpaces.Spaces[0], 0, - {0, 2, 4, UINT32_MAX}); - - DXILResourceBindingInfo::BindingSpaces &SamplerSpaces = - DRBI.getBindingSpaces(ResourceClass::Sampler); - EXPECT_EQ(SamplerSpaces.RC, ResourceClass::Sampler); - EXPECT_EQ(SamplerSpaces.Spaces.size(), 1u); - checkExpectedSpaceAndFreeRanges(SamplerSpaces.Spaces[0], 2, - {0, 3, 6, UINT32_MAX}); } -TEST_F(ResourceBindingAnalysisTest, TestUnboundedAndOverlap) { - // StructuredBuffer<float> A[] : register(t5); - // StructuredBuffer<float> B[3] : register(t0); - // StructuredBuffer<float> C[] : register(t0, space2); - // StructuredBuffer<float> D : register(t4, space2); /* overlapping */ +TEST_F(ResourceBindingAnalysisTest, TestOverlap) { + // StructuredBuffer<float> A[] : register(t0, space2); + // StructuredBuffer<float> B : register(t4, space2); /* overlapping */ StringRef Assembly = R"( define void @main() { entry: - %handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 -1, i32 10, i1 false, ptr null) - %handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 3, i32 0, i1 false, ptr null) - %handleC = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 0, i32 -1, i32 100, i1 false, ptr null) - %handleD = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 4, i32 1, i32 0, i1 false, ptr null) + %handleA = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 0, i32 -1, i32 100, i1 false, ptr null) + %handleB = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 4, i32 1, i32 0, i1 false, ptr null) ret void } )"; @@ -184,13 +84,6 @@ entry: EXPECT_EQ(false, DRBI.hasImplicitBinding()); EXPECT_EQ(true, DRBI.hasOverlappingBinding()); - - DXILResourceBindingInfo::BindingSpaces &SRVSpaces = - DRBI.getBindingSpaces(ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.Spaces.size(), 2u); - checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, {3, 4}); - checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[1], 2, {}); } TEST_F(ResourceBindingAnalysisTest, TestExactOverlap) { @@ -214,49 +107,6 @@ entry: EXPECT_EQ(false, DRBI.hasImplicitBinding()); EXPECT_EQ(true, DRBI.hasOverlappingBinding()); - - DXILResourceBindingInfo::BindingSpaces &SRVSpaces = - DRBI.getBindingSpaces(ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.RC, ResourceClass::SRV); - EXPECT_EQ(SRVSpaces.Spaces.size(), 1u); - checkExpectedSpaceAndFreeRanges(SRVSpaces.Spaces[0], 0, - {0, 4, 6, UINT32_MAX}); -} - -TEST_F(ResourceBindingAnalysisTest, TestEndOfRange) { - // RWBuffer<float> A : register(u4294967295); /* UINT32_MAX */ - // RWBuffer<float> B[10] : register(u4294967286, space1); - // /* range (UINT32_MAX - 9, UINT32_MAX )*/ - // RWBuffer<float> C[10] : register(u2147483647, space2); - // /* range (INT32_MAX, INT32_MAX + 9) */ - StringRef Assembly = R"( -%__cblayout_CB = type <{ i32 }> -define void @main() { -entry: - %handleA = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 -1, i32 1, i32 0, i1 false, ptr null) - %handleB = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 1, i32 -10, i32 10, i32 50, i1 false, ptr null) - %handleC = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 2147483647, i32 10, i32 100, i1 false, ptr null) - ret void -} - )"; - - auto M = parseAsm(Assembly); - - DXILResourceBindingInfo &DRBI = - MAM->getResult<DXILResourceBindingAnalysis>(*M); - - EXPECT_EQ(false, DRBI.hasImplicitBinding()); - EXPECT_EQ(false, DRBI.hasOverlappingBinding()); - - DXILResourceBindingInfo::BindingSpaces &UAVSpaces = - DRBI.getBindingSpaces(ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.Spaces.size(), 3u); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 0, {0, UINT32_MAX - 1}); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[1], 1, {0, UINT32_MAX - 10}); - checkExpectedSpaceAndFreeRanges( - UAVSpaces.Spaces[2], 2, - {0, (uint32_t)INT32_MAX - 1, (uint32_t)INT32_MAX + 10, UINT32_MAX}); } TEST_F(ResourceBindingAnalysisTest, TestImplicitFlag) { @@ -275,15 +125,8 @@ entry: DXILResourceBindingInfo &DRBI = MAM->getResult<DXILResourceBindingAnalysis>(*M); - EXPECT_EQ(true, DRBI.hasImplicitBinding()); - EXPECT_EQ(false, DRBI.hasOverlappingBinding()); - - DXILResourceBindingInfo::BindingSpaces &UAVSpaces = - DRBI.getBindingSpaces(ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.RC, ResourceClass::UAV); - EXPECT_EQ(UAVSpaces.Spaces.size(), 1u); - checkExpectedSpaceAndFreeRanges(UAVSpaces.Spaces[0], 100, - {0, 4, 6, UINT32_MAX}); + EXPECT_TRUE(DRBI.hasImplicitBinding()); + EXPECT_FALSE(DRBI.hasOverlappingBinding()); } } // namespace diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index 36408de..35927e3 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -758,6 +758,12 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::UnknownOS, T.getOS()); EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + T = Triple("riscv64-meta-unknown-mtia"); + EXPECT_EQ(Triple::riscv64, T.getArch()); + EXPECT_EQ(Triple::Meta, T.getVendor()); + EXPECT_EQ(Triple::UnknownOS, T.getOS()); + EXPECT_EQ(Triple::MTIA, T.getEnvironment()); + T = Triple("riscv64-unknown-linux"); EXPECT_EQ(Triple::riscv64, T.getArch()); EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp index 8012d9e..94b74d2 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -1075,7 +1075,7 @@ TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) { Args.push_back(I1); Args.push_back(I2); Args.push_back(M2); - VPBlendRecipe Recipe(Phi, Args); + VPBlendRecipe Recipe(Phi, Args, {}); EXPECT_TRUE(isa<VPUser>(&Recipe)); VPRecipeBase *BaseR = &Recipe; EXPECT_TRUE(isa<VPUser>(BaseR)); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp index 5394472..9e06c42 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -103,7 +103,7 @@ TEST_F(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) { auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); VPInstruction *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); - auto *Blend = new VPBlendRecipe(Phi, {DefI}); + auto *Blend = new VPBlendRecipe(Phi, {DefI}, {}); VPBasicBlock *VPBB1 = Plan.getEntry(); VPBasicBlock *VPBB2 = Plan.createVPBasicBlock(""); @@ -287,6 +287,42 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) { #endif } +TEST_F(VPVerifierTest, NonHeaderPHIInHeader) { + VPlan &Plan = getPlan(); + VPValue *Zero = Plan.getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(C), 0)); + auto *CanIV = new VPCanonicalIVPHIRecipe(Zero, {}); + auto *BranchOnCond = new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); + + VPBasicBlock *VPBB1 = Plan.getEntry(); + VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("header"); + + VPBB2->appendRecipe(CanIV); + + PHINode *PHINode = PHINode::Create(Type::getInt32Ty(C), 2); + auto *IRPhi = new VPIRPhi(*PHINode); + VPBB2->appendRecipe(IRPhi); + VPBB2->appendRecipe(BranchOnCond); + + VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB2, VPBB2, "R1"); + VPBlockUtils::connectBlocks(VPBB1, R1); + VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader()); + +#if GTEST_HAS_STREAM_REDIRECTION + ::testing::internal::CaptureStderr(); +#endif + EXPECT_FALSE(verifyVPlanIsValid(Plan)); +#if GTEST_HAS_STREAM_REDIRECTION +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + EXPECT_STREQ( + "Found non-header PHI recipe in header VPBB: IR <badref> = phi i32 \n", + ::testing::internal::GetCapturedStderr().c_str()); +#else + EXPECT_STREQ("Found non-header PHI recipe in header VPBB", + ::testing::internal::GetCapturedStderr().c_str()); +#endif +#endif +} + class VPIRVerifierTest : public VPlanTestIRBase {}; TEST_F(VPIRVerifierTest, testVerifyIRPhi) { |