1*134bec27SJames Molloy //===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===// 2*134bec27SJames Molloy // 3*134bec27SJames Molloy // The LLVM Compiler Infrastructure 4*134bec27SJames Molloy // 5*134bec27SJames Molloy // This file is distributed under the University of Illinois Open Source 6*134bec27SJames Molloy // License. See LICENSE.TXT for details. 7*134bec27SJames Molloy // 8*134bec27SJames Molloy //===----------------------------------------------------------------------===// 9*134bec27SJames Molloy 10*134bec27SJames Molloy #include "llvm/Analysis/ValueTracking.h" 11*134bec27SJames Molloy #include "llvm/AsmParser/Parser.h" 12*134bec27SJames Molloy #include "llvm/IR/Function.h" 13*134bec27SJames Molloy #include "llvm/IR/InstIterator.h" 14*134bec27SJames Molloy #include "llvm/IR/LLVMContext.h" 15*134bec27SJames Molloy #include "llvm/IR/Module.h" 16*134bec27SJames Molloy #include "llvm/Support/ErrorHandling.h" 17*134bec27SJames Molloy #include "llvm/Support/SourceMgr.h" 18*134bec27SJames Molloy #include "gtest/gtest.h" 19*134bec27SJames Molloy 20*134bec27SJames Molloy using namespace llvm; 21*134bec27SJames Molloy 22*134bec27SJames Molloy namespace { 23*134bec27SJames Molloy 24*134bec27SJames Molloy class MatchSelectPatternTest : public testing::Test { 25*134bec27SJames Molloy protected: 26*134bec27SJames Molloy void parseAssembly(const char *Assembly) { 27*134bec27SJames Molloy SMDiagnostic Error; 28*134bec27SJames Molloy M = parseAssemblyString(Assembly, Error, getGlobalContext()); 29*134bec27SJames Molloy 30*134bec27SJames Molloy std::string errMsg; 31*134bec27SJames Molloy raw_string_ostream os(errMsg); 32*134bec27SJames Molloy Error.print("", os); 33*134bec27SJames Molloy 34*134bec27SJames Molloy // A failure here means that the test itself is buggy. 35*134bec27SJames Molloy if (!M) 36*134bec27SJames Molloy report_fatal_error(os.str()); 37*134bec27SJames Molloy 38*134bec27SJames Molloy Function *F = M->getFunction("test"); 39*134bec27SJames Molloy if (F == nullptr) 40*134bec27SJames Molloy report_fatal_error("Test must have a function named @test"); 41*134bec27SJames Molloy 42*134bec27SJames Molloy A = nullptr; 43*134bec27SJames Molloy for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 44*134bec27SJames Molloy if (I->hasName()) { 45*134bec27SJames Molloy if (I->getName() == "A") 46*134bec27SJames Molloy A = &*I; 47*134bec27SJames Molloy } 48*134bec27SJames Molloy } 49*134bec27SJames Molloy if (A == nullptr) 50*134bec27SJames Molloy report_fatal_error("@test must have an instruction %A"); 51*134bec27SJames Molloy } 52*134bec27SJames Molloy 53*134bec27SJames Molloy void expectPattern(const SelectPatternResult &P) { 54*134bec27SJames Molloy Value *LHS, *RHS; 55*134bec27SJames Molloy Instruction::CastOps CastOp; 56*134bec27SJames Molloy SelectPatternResult R = matchSelectPattern(A, LHS, RHS, &CastOp); 57*134bec27SJames Molloy EXPECT_EQ(P.Flavor, R.Flavor); 58*134bec27SJames Molloy EXPECT_EQ(P.NaNBehavior, R.NaNBehavior); 59*134bec27SJames Molloy EXPECT_EQ(P.Ordered, R.Ordered); 60*134bec27SJames Molloy } 61*134bec27SJames Molloy 62*134bec27SJames Molloy std::unique_ptr<Module> M; 63*134bec27SJames Molloy Instruction *A, *B; 64*134bec27SJames Molloy }; 65*134bec27SJames Molloy 66*134bec27SJames Molloy } 67*134bec27SJames Molloy 68*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, SimpleFMin) { 69*134bec27SJames Molloy parseAssembly( 70*134bec27SJames Molloy "define float @test(float %a) {\n" 71*134bec27SJames Molloy " %1 = fcmp ult float %a, 5.0\n" 72*134bec27SJames Molloy " %A = select i1 %1, float %a, float 5.0\n" 73*134bec27SJames Molloy " ret float %A\n" 74*134bec27SJames Molloy "}\n"); 75*134bec27SJames Molloy expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false}); 76*134bec27SJames Molloy } 77*134bec27SJames Molloy 78*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, SimpleFMax) { 79*134bec27SJames Molloy parseAssembly( 80*134bec27SJames Molloy "define float @test(float %a) {\n" 81*134bec27SJames Molloy " %1 = fcmp ogt float %a, 5.0\n" 82*134bec27SJames Molloy " %A = select i1 %1, float %a, float 5.0\n" 83*134bec27SJames Molloy " ret float %A\n" 84*134bec27SJames Molloy "}\n"); 85*134bec27SJames Molloy expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 86*134bec27SJames Molloy } 87*134bec27SJames Molloy 88*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, SwappedFMax) { 89*134bec27SJames Molloy parseAssembly( 90*134bec27SJames Molloy "define float @test(float %a) {\n" 91*134bec27SJames Molloy " %1 = fcmp olt float 5.0, %a\n" 92*134bec27SJames Molloy " %A = select i1 %1, float %a, float 5.0\n" 93*134bec27SJames Molloy " ret float %A\n" 94*134bec27SJames Molloy "}\n"); 95*134bec27SJames Molloy expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false}); 96*134bec27SJames Molloy } 97*134bec27SJames Molloy 98*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, SwappedFMax2) { 99*134bec27SJames Molloy parseAssembly( 100*134bec27SJames Molloy "define float @test(float %a) {\n" 101*134bec27SJames Molloy " %1 = fcmp olt float %a, 5.0\n" 102*134bec27SJames Molloy " %A = select i1 %1, float 5.0, float %a\n" 103*134bec27SJames Molloy " ret float %A\n" 104*134bec27SJames Molloy "}\n"); 105*134bec27SJames Molloy expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false}); 106*134bec27SJames Molloy } 107*134bec27SJames Molloy 108*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, SwappedFMax3) { 109*134bec27SJames Molloy parseAssembly( 110*134bec27SJames Molloy "define float @test(float %a) {\n" 111*134bec27SJames Molloy " %1 = fcmp ult float %a, 5.0\n" 112*134bec27SJames Molloy " %A = select i1 %1, float 5.0, float %a\n" 113*134bec27SJames Molloy " ret float %A\n" 114*134bec27SJames Molloy "}\n"); 115*134bec27SJames Molloy expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true}); 116*134bec27SJames Molloy } 117*134bec27SJames Molloy 118*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, FastFMin) { 119*134bec27SJames Molloy parseAssembly( 120*134bec27SJames Molloy "define float @test(float %a) {\n" 121*134bec27SJames Molloy " %1 = fcmp nnan olt float %a, 5.0\n" 122*134bec27SJames Molloy " %A = select i1 %1, float %a, float 5.0\n" 123*134bec27SJames Molloy " ret float %A\n" 124*134bec27SJames Molloy "}\n"); 125*134bec27SJames Molloy expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false}); 126*134bec27SJames Molloy } 127*134bec27SJames Molloy 128*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, FMinConstantZero) { 129*134bec27SJames Molloy parseAssembly( 130*134bec27SJames Molloy "define float @test(float %a) {\n" 131*134bec27SJames Molloy " %1 = fcmp ole float %a, 0.0\n" 132*134bec27SJames Molloy " %A = select i1 %1, float %a, float 0.0\n" 133*134bec27SJames Molloy " ret float %A\n" 134*134bec27SJames Molloy "}\n"); 135*134bec27SJames Molloy // This shouldn't be matched, as %a could be -0.0. 136*134bec27SJames Molloy expectPattern({SPF_UNKNOWN, SPNB_NA, false}); 137*134bec27SJames Molloy } 138*134bec27SJames Molloy 139*134bec27SJames Molloy TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) { 140*134bec27SJames Molloy parseAssembly( 141*134bec27SJames Molloy "define float @test(float %a) {\n" 142*134bec27SJames Molloy " %1 = fcmp nsz ole float %a, 0.0\n" 143*134bec27SJames Molloy " %A = select i1 %1, float %a, float 0.0\n" 144*134bec27SJames Molloy " ret float %A\n" 145*134bec27SJames Molloy "}\n"); 146*134bec27SJames Molloy // But this should be, because we've ignored signed zeroes. 147*134bec27SJames Molloy expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true}); 148*134bec27SJames Molloy } 149