[llvm] r305308 - Fix m_[Ord|Unord][FMin|FMax] matchers to correctly match ordering.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 13 10:18:45 PDT 2017


Author: ctopper
Date: Tue Jun 13 12:18:45 2017
New Revision: 305308

URL: http://llvm.org/viewvc/llvm-project?rev=305308&view=rev
Log:
Fix m_[Ord|Unord][FMin|FMax] matchers to correctly match ordering.

Previously, the matching was done incorrectly for the case where
operands for FCmpInst and SelectInst were in opposite order.

Patch by Andrei Elovikov.

Differential Revision: https://reviews.llvm.org/D33185

Modified:
    llvm/trunk/include/llvm/IR/PatternMatch.h
    llvm/trunk/unittests/IR/PatternMatch.cpp

Modified: llvm/trunk/include/llvm/IR/PatternMatch.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PatternMatch.h?rev=305308&r1=305307&r2=305308&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PatternMatch.h (original)
+++ llvm/trunk/include/llvm/IR/PatternMatch.h Tue Jun 13 12:18:45 2017
@@ -1027,7 +1027,7 @@ struct MaxMin_match {
         (TrueVal != RHS || FalseVal != LHS))
       return false;
     typename CmpInst_t::Predicate Pred =
-        LHS == TrueVal ? Cmp->getPredicate() : Cmp->getSwappedPredicate();
+        LHS == TrueVal ? Cmp->getPredicate() : Cmp->getInversePredicate();
     // Does "(x pred y) ? x : y" represent the desired max/min operation?
     if (!Pred_t::match(Pred))
       return false;
@@ -1138,7 +1138,7 @@ inline MaxMin_match<FCmpInst, LHS, RHS,
 /// semantics. In the presence of 'NaN' we have to preserve the original
 /// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
 ///
-///                         max(L, R)  iff L and R are not NaN
+///                         min(L, R)  iff L and R are not NaN
 ///  m_OrdFMin(L, R) =      R          iff L or R are NaN
 template <typename LHS, typename RHS>
 inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
@@ -1154,13 +1154,28 @@ inline MaxMin_match<FCmpInst, LHS, RHS,
 /// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
 ///
 ///                         max(L, R)  iff L and R are not NaN
-///  m_UnordFMin(L, R) =    L          iff L or R are NaN
+///  m_UnordFMax(L, R) =    L          iff L or R are NaN
 template <typename LHS, typename RHS>
 inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
 m_UnordFMax(const LHS &L, const RHS &R) {
   return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
 }
 
+/// \brief Match an 'unordered' floating point minimum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
+///
+///                          min(L, R)  iff L and R are not NaN
+///  m_UnordFMin(L, R) =     L          iff L or R are NaN
+template <typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
+m_UnordFMin(const LHS &L, const RHS &R) {
+  return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
+}
+
 //===----------------------------------------------------------------------===//
 // Matchers for overflow check patterns: e.g. (a + b) u< a
 //
@@ -1207,21 +1222,6 @@ m_UAddWithOverflow(const LHS_t &L, const
   return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
 }
 
-/// \brief Match an 'unordered' floating point minimum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
-///
-///                          max(L, R)  iff L and R are not NaN
-///  m_UnordFMin(L, R) =     L          iff L or R are NaN
-template <typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
-m_UnordFMin(const LHS &L, const RHS &R) {
-  return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
-}
-
 template <typename Opnd_t> struct Argument_match {
   unsigned OpI;
   Opnd_t Val;

Modified: llvm/trunk/unittests/IR/PatternMatch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PatternMatch.cpp?rev=305308&r1=305307&r2=305308&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PatternMatch.cpp (original)
+++ llvm/trunk/unittests/IR/PatternMatch.cpp Tue Jun 13 12:18:45 2017
@@ -91,15 +91,26 @@ TEST_F(PatternMatchTest, FloatingPointOr
   EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
                    .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
 
-  // Test match on OGE with inverted select.
-  EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+  // Test inverted selects. Note, that this "inverts" the ordering, e.g.:
+  // %cmp = fcmp oge L, R
+  // %min = select %cmp R, L
+  // Given L == NaN
+  // the above is expanded to %cmp == false ==> %min = L
+  // which is true for UnordFMin, not OrdFMin, so test that:
+
+  // [OU]GE with inverted select.
+  EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
+  EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 
-  // Test match on OGT with inverted select.
-  EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+  // [OU]GT with inverted select.
+  EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
+  EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 }
@@ -130,15 +141,27 @@ TEST_F(PatternMatchTest, FloatingPointOr
   EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
                    .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
 
-  // Test match on OLE with inverted select.
+
+  // Test inverted selects. Note, that this "inverts" the ordering, e.g.:
+  // %cmp = fcmp ole L, R
+  // %max = select %cmp, R, L
+  // Given L == NaN,
+  // the above is expanded to %cmp == false ==> %max == L
+  // which is true for UnordFMax, not OrdFMax, so test that:
+
+  // [OU]LE with inverted select.
+  EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+                   .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
   EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
-                  .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
+                  .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 
-  // Test match on OLT with inverted select.
+  // [OUT]LT with inverted select.
+  EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
+                   .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
   EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
-                  .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
+                  .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 }
@@ -169,15 +192,26 @@ TEST_F(PatternMatchTest, FloatingPointUn
   EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
                    .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
 
-  // Test match on UGE with inverted select.
-  EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+  // Test inverted selects. Note, that this "inverts" the ordering, e.g.:
+  // %cmp = fcmp uge L, R
+  // %min = select %cmp R, L
+  // Given L == NaN
+  // the above is expanded to %cmp == true ==> %min = R
+  // which is true for OrdFMin, not UnordFMin, so test that:
+
+  // [UO]GE with inverted select.
+  EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
+  EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 
-  // Test match on UGT with inverted select.
-  EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+  // [UO]GT with inverted select.
+  EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
+  EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 }
@@ -208,15 +242,26 @@ TEST_F(PatternMatchTest, FloatingPointUn
   EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
                    .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
 
-  // Test match on ULE with inverted select.
-  EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+  // Test inverted selects. Note, that this "inverts" the ordering, e.g.:
+  // %cmp = fcmp ule L, R
+  // %max = select %cmp R, L
+  // Given L == NaN
+  // the above is expanded to %cmp == true ==> %max = R
+  // which is true for OrdFMax, not UnordFMax, so test that:
+
+  // [UO]LE with inverted select.
+  EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
+  EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 
-  // Test match on ULT with inverted select.
-  EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+  // [UO]LT with inverted select.
+  EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
                   .match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
+  EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
+                  .match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
   EXPECT_EQ(L, MatchL);
   EXPECT_EQ(R, MatchR);
 }




More information about the llvm-commits mailing list