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