blob: f429c3b991495a331f71a9938eca37671eaaaa09 [file] [log] [blame]
James Molloy134bec22015-08-11 09:12:57 +00001//===- 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
20using namespace llvm;
21
22namespace {
23
24class MatchSelectPatternTest : public testing::Test {
25protected:
26 void parseAssembly(const char *Assembly) {
27 SMDiagnostic Error;
Mehdi Amini03b42e42016-04-14 21:59:01 +000028 M = parseAssemblyString(Assembly, Error, Context);
James Molloy134bec22015-08-11 09:12:57 +000029
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
Mehdi Amini03b42e42016-04-14 21:59:01 +000062 LLVMContext Context;
James Molloy134bec22015-08-11 09:12:57 +000063 std::unique_ptr<Module> M;
64 Instruction *A, *B;
65};
66
67}
68
69TEST_F(MatchSelectPatternTest, SimpleFMin) {
70 parseAssembly(
71 "define float @test(float %a) {\n"
72 " %1 = fcmp ult float %a, 5.0\n"
73 " %A = select i1 %1, float %a, float 5.0\n"
74 " ret float %A\n"
75 "}\n");
76 expectPattern({SPF_FMINNUM, SPNB_RETURNS_NAN, false});
77}
78
79TEST_F(MatchSelectPatternTest, SimpleFMax) {
80 parseAssembly(
81 "define float @test(float %a) {\n"
82 " %1 = fcmp ogt float %a, 5.0\n"
83 " %A = select i1 %1, float %a, float 5.0\n"
84 " ret float %A\n"
85 "}\n");
86 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
87}
88
89TEST_F(MatchSelectPatternTest, SwappedFMax) {
90 parseAssembly(
91 "define float @test(float %a) {\n"
92 " %1 = fcmp olt float 5.0, %a\n"
93 " %A = select i1 %1, float %a, float 5.0\n"
94 " ret float %A\n"
95 "}\n");
96 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, false});
97}
98
99TEST_F(MatchSelectPatternTest, SwappedFMax2) {
100 parseAssembly(
101 "define float @test(float %a) {\n"
102 " %1 = fcmp olt float %a, 5.0\n"
103 " %A = select i1 %1, float 5.0, float %a\n"
104 " ret float %A\n"
105 "}\n");
106 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_NAN, false});
107}
108
109TEST_F(MatchSelectPatternTest, SwappedFMax3) {
110 parseAssembly(
111 "define float @test(float %a) {\n"
112 " %1 = fcmp ult float %a, 5.0\n"
113 " %A = select i1 %1, float 5.0, float %a\n"
114 " ret float %A\n"
115 "}\n");
116 expectPattern({SPF_FMAXNUM, SPNB_RETURNS_OTHER, true});
117}
118
119TEST_F(MatchSelectPatternTest, FastFMin) {
120 parseAssembly(
121 "define float @test(float %a) {\n"
122 " %1 = fcmp nnan olt float %a, 5.0\n"
123 " %A = select i1 %1, float %a, float 5.0\n"
124 " ret float %A\n"
125 "}\n");
126 expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
127}
128
129TEST_F(MatchSelectPatternTest, FMinConstantZero) {
130 parseAssembly(
131 "define float @test(float %a) {\n"
132 " %1 = fcmp ole float %a, 0.0\n"
133 " %A = select i1 %1, float %a, float 0.0\n"
134 " ret float %A\n"
135 "}\n");
136 // This shouldn't be matched, as %a could be -0.0.
137 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
138}
139
140TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
141 parseAssembly(
142 "define float @test(float %a) {\n"
143 " %1 = fcmp nsz ole float %a, 0.0\n"
144 " %A = select i1 %1, float %a, float 0.0\n"
145 " ret float %A\n"
146 "}\n");
147 // But this should be, because we've ignored signed zeroes.
148 expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
149}
James Molloy569cea62015-09-02 17:25:25 +0000150
151TEST_F(MatchSelectPatternTest, DoubleCastU) {
152 parseAssembly(
153 "define i32 @test(i8 %a, i8 %b) {\n"
154 " %1 = icmp ult i8 %a, %b\n"
155 " %2 = zext i8 %a to i32\n"
156 " %3 = zext i8 %b to i32\n"
157 " %A = select i1 %1, i32 %2, i32 %3\n"
158 " ret i32 %A\n"
159 "}\n");
160 // We should be able to look through the situation where we cast both operands
161 // to the select.
162 expectPattern({SPF_UMIN, SPNB_NA, false});
163}
164
165TEST_F(MatchSelectPatternTest, DoubleCastS) {
166 parseAssembly(
167 "define i32 @test(i8 %a, i8 %b) {\n"
168 " %1 = icmp slt i8 %a, %b\n"
169 " %2 = sext i8 %a to i32\n"
170 " %3 = sext i8 %b to i32\n"
171 " %A = select i1 %1, i32 %2, i32 %3\n"
172 " ret i32 %A\n"
173 "}\n");
174 // We should be able to look through the situation where we cast both operands
175 // to the select.
176 expectPattern({SPF_SMIN, SPNB_NA, false});
177}
178
179TEST_F(MatchSelectPatternTest, DoubleCastBad) {
180 parseAssembly(
181 "define i32 @test(i8 %a, i8 %b) {\n"
182 " %1 = icmp ult i8 %a, %b\n"
183 " %2 = zext i8 %a to i32\n"
184 " %3 = sext i8 %b to i32\n"
185 " %A = select i1 %1, i32 %2, i32 %3\n"
186 " ret i32 %A\n"
187 "}\n");
James Molloy687a8442015-09-02 17:29:54 +0000188 // The cast types here aren't the same, so we cannot match an UMIN.
James Molloy569cea62015-09-02 17:25:25 +0000189 expectPattern({SPF_UNKNOWN, SPNB_NA, false});
190}