PatternMatch: Matcher for (un)ordered floating point min/max
[oota-llvm.git] / unittests / IR / PatternMatch.cpp
1 //===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit 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/ADT/STLExtras.h"
11 #include "llvm/Analysis/ValueTracking.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/DataLayout.h"
15 #include "llvm/IR/DerivedTypes.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/MDBuilder.h"
20 #include "llvm/IR/Operator.h"
21 #include "llvm/Support/NoFolder.h"
22 #include "llvm/Support/PatternMatch.h"
23 #include "gtest/gtest.h"
24
25 using namespace llvm::PatternMatch;
26
27 namespace llvm {
28 namespace {
29
30 /// Ordered floating point minimum/maximum tests.
31
32 static void m_OrdFMin_expect_match_and_delete(Value *Cmp, Value *Select,
33                                               Value *L, Value *R) {
34   Value *MatchL, *MatchR;
35   EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
36   EXPECT_EQ(L, MatchL);
37   EXPECT_EQ(R, MatchR);
38   delete Select;
39   delete Cmp;
40 }
41
42 static void m_OrdFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
43                                                 Value *L, Value *R) {
44   Value *MatchL, *MatchR;
45   EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
46   delete Select;
47   delete Cmp;
48 }
49
50 static void m_OrdFMax_expect_match_and_delete(Value *Cmp, Value *Select,
51                                               Value *L, Value *R) {
52   Value *MatchL, *MatchR;
53   EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
54   EXPECT_EQ(L, MatchL);
55   EXPECT_EQ(R, MatchR);
56   delete Select;
57   delete Cmp;
58 }
59
60 static void m_OrdFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
61                                                 Value *L, Value *R) {
62   Value *MatchL, *MatchR;
63   EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
64   delete Select;
65   delete Cmp;
66 }
67
68
69
70 TEST(PatternMatchTest, FloatingPointOrderedMin) {
71   LLVMContext &C(getGlobalContext());
72   IRBuilder<true, NoFolder> Builder(C);
73
74   Type *FltTy = Builder.getFloatTy();
75   Value *L = ConstantFP::get(FltTy, 1.0);
76   Value *R = ConstantFP::get(FltTy, 2.0);
77
78   // Test OLT.
79   Value *Cmp = Builder.CreateFCmpOLT(L, R);
80   Value *Select = Builder.CreateSelect(Cmp, L, R);
81   m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
82
83   // Test OLE.
84   Cmp = Builder.CreateFCmpOLE(L, R);
85   Select = Builder.CreateSelect(Cmp, L, R);
86   m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
87
88   // Test no match on OGE.
89   Cmp = Builder.CreateFCmpOGE(L, R);
90   Select = Builder.CreateSelect(Cmp, L, R);
91   m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
92
93   // Test no match on OGT.
94   Cmp = Builder.CreateFCmpOGT(L, R);
95   Select = Builder.CreateSelect(Cmp, L, R);
96   m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
97
98   // Test match on OGE with inverted select.
99   Cmp = Builder.CreateFCmpOGE(L, R);
100   Select = Builder.CreateSelect(Cmp, R, L);
101   m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
102
103   // Test match on OGT with inverted select.
104   Cmp = Builder.CreateFCmpOGT(L, R);
105   Select = Builder.CreateSelect(Cmp, R, L);
106   m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
107 }
108
109 TEST(PatternMatchTest, FloatingPointOrderedMax) {
110   LLVMContext &C(getGlobalContext());
111   IRBuilder<true, NoFolder> Builder(C);
112
113   Type *FltTy = Builder.getFloatTy();
114   Value *L = ConstantFP::get(FltTy, 1.0);
115   Value *R = ConstantFP::get(FltTy, 2.0);
116
117   // Test OGT.
118   Value *Cmp = Builder.CreateFCmpOGT(L, R);
119   Value *Select = Builder.CreateSelect(Cmp, L, R);
120   m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
121
122   // Test OGE.
123   Cmp = Builder.CreateFCmpOGE(L, R);
124   Select = Builder.CreateSelect(Cmp, L, R);
125   m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
126
127   // Test no match on OLE.
128   Cmp = Builder.CreateFCmpOLE(L, R);
129   Select = Builder.CreateSelect(Cmp, L, R);
130   m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
131
132   // Test no match on OLT.
133   Cmp = Builder.CreateFCmpOLT(L, R);
134   Select = Builder.CreateSelect(Cmp, L, R);
135   m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
136
137   // Test match on OLE with inverted select.
138   Cmp = Builder.CreateFCmpOLE(L, R);
139   Select = Builder.CreateSelect(Cmp, R, L);
140   m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
141
142   // Test match on OLT with inverted select.
143   Cmp = Builder.CreateFCmpOLT(L, R);
144   Select = Builder.CreateSelect(Cmp, R, L);
145   m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
146 }
147
148 /// Unordered floating point minimum/maximum tests.
149
150 static void m_UnordFMin_expect_match_and_delete(Value *Cmp, Value *Select,
151                                               Value *L, Value *R) {
152   Value *MatchL, *MatchR;
153   EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
154   EXPECT_EQ(L, MatchL);
155   EXPECT_EQ(R, MatchR);
156   delete Select;
157   delete Cmp;
158 }
159
160 static void m_UnordFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
161                                                 Value *L, Value *R) {
162   Value *MatchL, *MatchR;
163   EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
164   delete Select;
165   delete Cmp;
166 }
167
168 static void m_UnordFMax_expect_match_and_delete(Value *Cmp, Value *Select,
169                                               Value *L, Value *R) {
170   Value *MatchL, *MatchR;
171   EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
172   EXPECT_EQ(L, MatchL);
173   EXPECT_EQ(R, MatchR);
174   delete Select;
175   delete Cmp;
176 }
177
178 static void m_UnordFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
179                                                 Value *L, Value *R) {
180   Value *MatchL, *MatchR;
181   EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
182   delete Select;
183   delete Cmp;
184 }
185
186 TEST(PatternMatchTest, FloatingPointUnorderedMin) {
187   LLVMContext &C(getGlobalContext());
188   IRBuilder<true, NoFolder> Builder(C);
189
190   Type *FltTy = Builder.getFloatTy();
191   Value *L = ConstantFP::get(FltTy, 1.0);
192   Value *R = ConstantFP::get(FltTy, 2.0);
193
194   // Test ULT.
195   Value *Cmp = Builder.CreateFCmpULT(L, R);
196   Value *Select = Builder.CreateSelect(Cmp, L, R);
197   m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
198
199   // Test ULE.
200   Cmp = Builder.CreateFCmpULE(L, R);
201   Select = Builder.CreateSelect(Cmp, L, R);
202   m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
203
204   // Test no match on UGE.
205   Cmp = Builder.CreateFCmpUGE(L, R);
206   Select = Builder.CreateSelect(Cmp, L, R);
207   m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
208
209   // Test no match on UGT.
210   Cmp = Builder.CreateFCmpUGT(L, R);
211   Select = Builder.CreateSelect(Cmp, L, R);
212   m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
213
214   // Test match on UGE with inverted select.
215   Cmp = Builder.CreateFCmpUGE(L, R);
216   Select = Builder.CreateSelect(Cmp, R, L);
217   m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
218
219   // Test match on UGT with inverted select.
220   Cmp = Builder.CreateFCmpUGT(L, R);
221   Select = Builder.CreateSelect(Cmp, R, L);
222   m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
223 }
224
225 TEST(PatternMatchTest, FloatingPointUnorderedMax) {
226   LLVMContext &C(getGlobalContext());
227   IRBuilder<true, NoFolder> Builder(C);
228
229   Type *FltTy = Builder.getFloatTy();
230   Value *L = ConstantFP::get(FltTy, 1.0);
231   Value *R = ConstantFP::get(FltTy, 2.0);
232
233   // Test UGT.
234   Value *Cmp = Builder.CreateFCmpUGT(L, R);
235   Value *Select = Builder.CreateSelect(Cmp, L, R);
236   m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
237
238   // Test UGE.
239   Cmp = Builder.CreateFCmpUGE(L, R);
240   Select = Builder.CreateSelect(Cmp, L, R);
241   m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
242
243   // Test no match on ULE.
244   Cmp = Builder.CreateFCmpULE(L, R);
245   Select = Builder.CreateSelect(Cmp, L, R);
246   m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
247
248   // Test no match on ULT.
249   Cmp = Builder.CreateFCmpULT(L, R);
250   Select = Builder.CreateSelect(Cmp, L, R);
251   m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
252
253   // Test match on ULE with inverted select.
254   Cmp = Builder.CreateFCmpULE(L, R);
255   Select = Builder.CreateSelect(Cmp, R, L);
256   m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
257
258   // Test match on ULT with inverted select.
259   Cmp = Builder.CreateFCmpULT(L, R);
260   Select = Builder.CreateSelect(Cmp, R, L);
261   m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
262 }
263
264 } // anonymous namespace.
265 } // llvm namespace.