PatternMatch.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. #include "llvm/ADT/STLExtras.h"
  10. #include "llvm/Analysis/ValueTracking.h"
  11. #include "llvm/IR/BasicBlock.h"
  12. #include "llvm/IR/Constants.h"
  13. #include "llvm/IR/DataLayout.h"
  14. #include "llvm/IR/DerivedTypes.h"
  15. #include "llvm/IR/Function.h"
  16. #include "llvm/IR/IRBuilder.h"
  17. #include "llvm/IR/Instructions.h"
  18. #include "llvm/IR/LLVMContext.h"
  19. #include "llvm/IR/MDBuilder.h"
  20. #include "llvm/IR/Module.h"
  21. #include "llvm/IR/NoFolder.h"
  22. #include "llvm/IR/Operator.h"
  23. #include "llvm/IR/PatternMatch.h"
  24. #include "llvm/IR/Type.h"
  25. #include "gtest/gtest.h"
  26. using namespace llvm;
  27. using namespace llvm::PatternMatch;
  28. namespace {
  29. struct PatternMatchTest : ::testing::Test {
  30. LLVMContext Ctx;
  31. std::unique_ptr<Module> M;
  32. Function *F;
  33. BasicBlock *BB;
  34. IRBuilder<true, NoFolder> IRB;
  35. PatternMatchTest()
  36. : M(new Module("PatternMatchTestModule", Ctx)),
  37. F(Function::Create(
  38. FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
  39. Function::ExternalLinkage, "f", M.get())),
  40. BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
  41. };
  42. TEST_F(PatternMatchTest, OneUse) {
  43. // Build up a little tree of values:
  44. //
  45. // One = (1 + 2) + 42
  46. // Two = One + 42
  47. // Leaf = (Two + 8) + (Two + 13)
  48. Value *One = IRB.CreateAdd(IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(2)),
  49. IRB.getInt32(42));
  50. Value *Two = IRB.CreateAdd(One, IRB.getInt32(42));
  51. Value *Leaf = IRB.CreateAdd(IRB.CreateAdd(Two, IRB.getInt32(8)),
  52. IRB.CreateAdd(Two, IRB.getInt32(13)));
  53. Value *V;
  54. EXPECT_TRUE(m_OneUse(m_Value(V)).match(One));
  55. EXPECT_EQ(One, V);
  56. EXPECT_FALSE(m_OneUse(m_Value()).match(Two));
  57. EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));
  58. }
  59. TEST_F(PatternMatchTest, FloatingPointOrderedMin) {
  60. Type *FltTy = IRB.getFloatTy();
  61. Value *L = ConstantFP::get(FltTy, 1.0);
  62. Value *R = ConstantFP::get(FltTy, 2.0);
  63. Value *MatchL, *MatchR;
  64. // Test OLT.
  65. EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  66. .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
  67. EXPECT_EQ(L, MatchL);
  68. EXPECT_EQ(R, MatchR);
  69. // Test OLE.
  70. EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  71. .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
  72. EXPECT_EQ(L, MatchL);
  73. EXPECT_EQ(R, MatchR);
  74. // Test no match on OGE.
  75. EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  76. .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
  77. // Test no match on OGT.
  78. EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  79. .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
  80. // Test match on OGE with inverted select.
  81. EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  82. .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
  83. EXPECT_EQ(L, MatchL);
  84. EXPECT_EQ(R, MatchR);
  85. // Test match on OGT with inverted select.
  86. EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
  87. .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
  88. EXPECT_EQ(L, MatchL);
  89. EXPECT_EQ(R, MatchR);
  90. }
  91. TEST_F(PatternMatchTest, FloatingPointOrderedMax) {
  92. Type *FltTy = IRB.getFloatTy();
  93. Value *L = ConstantFP::get(FltTy, 1.0);
  94. Value *R = ConstantFP::get(FltTy, 2.0);
  95. Value *MatchL, *MatchR;
  96. // Test OGT.
  97. EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  98. .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
  99. EXPECT_EQ(L, MatchL);
  100. EXPECT_EQ(R, MatchR);
  101. // Test OGE.
  102. EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  103. .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
  104. EXPECT_EQ(L, MatchL);
  105. EXPECT_EQ(R, MatchR);
  106. // Test no match on OLE.
  107. EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  108. .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
  109. // Test no match on OLT.
  110. EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  111. .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
  112. // Test match on OLE with inverted select.
  113. EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  114. .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
  115. EXPECT_EQ(L, MatchL);
  116. EXPECT_EQ(R, MatchR);
  117. // Test match on OLT with inverted select.
  118. EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
  119. .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
  120. EXPECT_EQ(L, MatchL);
  121. EXPECT_EQ(R, MatchR);
  122. }
  123. TEST_F(PatternMatchTest, FloatingPointUnorderedMin) {
  124. Type *FltTy = IRB.getFloatTy();
  125. Value *L = ConstantFP::get(FltTy, 1.0);
  126. Value *R = ConstantFP::get(FltTy, 2.0);
  127. Value *MatchL, *MatchR;
  128. // Test ULT.
  129. EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  130. .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
  131. EXPECT_EQ(L, MatchL);
  132. EXPECT_EQ(R, MatchR);
  133. // Test ULE.
  134. EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  135. .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
  136. EXPECT_EQ(L, MatchL);
  137. EXPECT_EQ(R, MatchR);
  138. // Test no match on UGE.
  139. EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  140. .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
  141. // Test no match on UGT.
  142. EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  143. .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
  144. // Test match on UGE with inverted select.
  145. EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  146. .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
  147. EXPECT_EQ(L, MatchL);
  148. EXPECT_EQ(R, MatchR);
  149. // Test match on UGT with inverted select.
  150. EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
  151. .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
  152. EXPECT_EQ(L, MatchL);
  153. EXPECT_EQ(R, MatchR);
  154. }
  155. TEST_F(PatternMatchTest, FloatingPointUnorderedMax) {
  156. Type *FltTy = IRB.getFloatTy();
  157. Value *L = ConstantFP::get(FltTy, 1.0);
  158. Value *R = ConstantFP::get(FltTy, 2.0);
  159. Value *MatchL, *MatchR;
  160. // Test UGT.
  161. EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  162. .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
  163. EXPECT_EQ(L, MatchL);
  164. EXPECT_EQ(R, MatchR);
  165. // Test UGE.
  166. EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  167. .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
  168. EXPECT_EQ(L, MatchL);
  169. EXPECT_EQ(R, MatchR);
  170. // Test no match on ULE.
  171. EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  172. .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
  173. // Test no match on ULT.
  174. EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  175. .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
  176. // Test match on ULE with inverted select.
  177. EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  178. .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
  179. EXPECT_EQ(L, MatchL);
  180. EXPECT_EQ(R, MatchR);
  181. // Test match on ULT with inverted select.
  182. EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
  183. .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
  184. EXPECT_EQ(L, MatchL);
  185. EXPECT_EQ(R, MatchR);
  186. }
  187. TEST_F(PatternMatchTest, OverflowingBinOps) {
  188. Value *L = IRB.getInt32(1);
  189. Value *R = IRB.getInt32(2);
  190. Value *MatchL, *MatchR;
  191. EXPECT_TRUE(
  192. m_NSWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWAdd(L, R)));
  193. EXPECT_EQ(L, MatchL);
  194. EXPECT_EQ(R, MatchR);
  195. MatchL = MatchR = nullptr;
  196. EXPECT_TRUE(
  197. m_NSWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWSub(L, R)));
  198. EXPECT_EQ(L, MatchL);
  199. EXPECT_EQ(R, MatchR);
  200. MatchL = MatchR = nullptr;
  201. EXPECT_TRUE(
  202. m_NSWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWMul(L, R)));
  203. EXPECT_EQ(L, MatchL);
  204. EXPECT_EQ(R, MatchR);
  205. MatchL = MatchR = nullptr;
  206. EXPECT_TRUE(m_NSWShl(m_Value(MatchL), m_Value(MatchR)).match(
  207. IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
  208. EXPECT_EQ(L, MatchL);
  209. EXPECT_EQ(R, MatchR);
  210. EXPECT_TRUE(
  211. m_NUWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWAdd(L, R)));
  212. EXPECT_EQ(L, MatchL);
  213. EXPECT_EQ(R, MatchR);
  214. MatchL = MatchR = nullptr;
  215. EXPECT_TRUE(
  216. m_NUWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWSub(L, R)));
  217. EXPECT_EQ(L, MatchL);
  218. EXPECT_EQ(R, MatchR);
  219. MatchL = MatchR = nullptr;
  220. EXPECT_TRUE(
  221. m_NUWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWMul(L, R)));
  222. EXPECT_EQ(L, MatchL);
  223. EXPECT_EQ(R, MatchR);
  224. MatchL = MatchR = nullptr;
  225. EXPECT_TRUE(m_NUWShl(m_Value(MatchL), m_Value(MatchR)).match(
  226. IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
  227. EXPECT_EQ(L, MatchL);
  228. EXPECT_EQ(R, MatchR);
  229. EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
  230. EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
  231. EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
  232. EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
  233. EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
  234. EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
  235. EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
  236. EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNUWMul(L, R)));
  237. EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
  238. EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
  239. EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(
  240. IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
  241. EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
  242. EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
  243. EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
  244. EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
  245. EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
  246. EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
  247. EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
  248. EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
  249. EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNSWMul(L, R)));
  250. EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
  251. EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
  252. EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(
  253. IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
  254. EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
  255. }
  256. } // anonymous namespace.