diff options
Diffstat (limited to 'llvm/unittests')
-rw-r--r-- | llvm/unittests/Analysis/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/Analysis/ValueTrackingTest.cpp | 148 |
2 files changed, 149 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt index 35a6d92ce17..28d35ceec92 100644 --- a/llvm/unittests/Analysis/CMakeLists.txt +++ b/llvm/unittests/Analysis/CMakeLists.txt @@ -13,4 +13,5 @@ add_llvm_unittest(AnalysisTests LazyCallGraphTest.cpp ScalarEvolutionTest.cpp MixedTBAATest.cpp + ValueTrackingTest.cpp ) diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp new file mode 100644 index 00000000000..b5ad01968b9 --- /dev/null +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -0,0 +1,148 @@ +//===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SourceMgr.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +class MatchSelectPatternTest : public testing::Test { +protected: + void parseAssembly(const char *Assembly) { + SMDiagnostic Error; + M = parseAssemblyString(Assembly, Error, getGlobalContext()); + + std::string errMsg; + raw_string_ostream os(errMsg); + Error.print("", os); + + // A failure here means that the test itself is buggy. + if (!M) + report_fatal_error(os.str()); + + Function *F = M->getFunction("test"); + if (F == nullptr) + report_fatal_error("Test must have a function named @test"); + + A = nullptr; + for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { + if (I->hasName()) { + if (I->getName() == "A") + A = &*I; + } + } + if (A == nullptr) + report_fatal_error("@test must have an instruction %A"); + } + + void expectPattern(const SelectPatternResult &P) { + Value *LHS, *RHS; + Instruction::CastOps CastOp; + SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp); + EXPECT_EQ(P.Flavor, R.Flavor); + EXPECT_EQ(P.NaNBehavior, R.NaNBehavior); + EXPECT_EQ(P.Ordered, R.Ordered); + } + + std::unique_ptr<Module> M; + Instruction *A, *B; +}; + +} + +TEST_F(MatchSelectPatternTest, SimpleFMin) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp ult float %a, 5.0\n" + " %A = select i1 %1, float %a, float 5.0\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); +} + +TEST_F(MatchSelectPatternTest, SimpleFMax) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp ogt float %a, 5.0\n" + " %A = select i1 %1, float %a, float 5.0\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); +} + +TEST_F(MatchSelectPatternTest, SwappedFMax) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp olt float 5.0, %a\n" + " %A = select i1 %1, float %a, float 5.0\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); +} + +TEST_F(MatchSelectPatternTest, SwappedFMax2) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp olt float %a, 5.0\n" + " %A = select i1 %1, float 5.0, float %a\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); +} + +TEST_F(MatchSelectPatternTest, SwappedFMax3) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp ult float %a, 5.0\n" + " %A = select i1 %1, float 5.0, float %a\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); +} + +TEST_F(MatchSelectPatternTest, FastFMin) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp nnan olt float %a, 5.0\n" + " %A = select i1 %1, float %a, float 5.0\n" + " ret float %A\n" + "}\n"); + expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false}); +} + +TEST_F(MatchSelectPatternTest, FMinConstantZero) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp ole float %a, 0.0\n" + " %A = select i1 %1, float %a, float 0.0\n" + " ret float %A\n" + "}\n"); + // This shouldn't be matched, as %a could be -0.0. + expectPattern({SPF_UNKNOWN, SPNB_NA, false}); +} + +TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { + parseAssembly( + "define float @test(float %a) {\n" + " %1 = fcmp nsz ole float %a, 0.0\n" + " %A = select i1 %1, float %a, float 0.0\n" + " ret float %A\n" + "}\n"); + // But this should be, because we've ignored signed zeroes. + expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); +} |