diff options
Diffstat (limited to 'llvm/unittests')
-rw-r--r-- | llvm/unittests/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/GlobalISel/LegalizerTest.cpp | 4 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp | 95 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp | 317 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/SelectionDAGPatternMatchTest.cpp | 94 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/SelectionDAGTestBase.h | 99 | ||||
-rw-r--r-- | llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp | 18 |
7 files changed, 433 insertions, 195 deletions
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/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 } |