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. 266