Skip to content

Commit 1713edf

Browse files
committed
Add m_OrdOrUnordFMax and m_OrdOrUnordFMin matchers
1 parent 76581cb commit 1713edf

File tree

5 files changed

+166
-16
lines changed

5 files changed

+166
-16
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,32 @@ m_UnordFMin(const LHS &L, const RHS &R) {
23872387
return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
23882388
}
23892389

2390+
/// Match an 'ordered' or 'unordered' floating point maximum function.
2391+
/// Floating point has one special value 'NaN'. Therefore, there is no total
2392+
/// order. However, if we can ignore the 'NaN' value (for example, because of a
2393+
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
2394+
/// semantics.
2395+
template <typename LHS, typename RHS>
2396+
inline match_combine_or<MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>,
2397+
MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>>
2398+
m_OrdOrUnordFMax(const LHS &L, const RHS &R) {
2399+
return m_CombineOr(MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R),
2400+
MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R));
2401+
}
2402+
2403+
/// Match an 'ordered' or 'unordered' floating point minimum function.
2404+
/// Floating point has one special value 'NaN'. Therefore, there is no total
2405+
/// order. However, if we can ignore the 'NaN' value (for example, because of a
2406+
/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
2407+
/// semantics.
2408+
template <typename LHS, typename RHS>
2409+
inline match_combine_or<MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>,
2410+
MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>>
2411+
m_OrdOrUnordFMin(const LHS &L, const RHS &R) {
2412+
return m_CombineOr(MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R),
2413+
MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R));
2414+
}
2415+
23902416
/// Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
23912417
/// NOTE: we first match the 'Not' (by matching '-1'),
23922418
/// and only then match the inner matcher!

llvm/lib/Analysis/IVDescriptors.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -690,13 +690,9 @@ RecurrenceDescriptor::isMinMaxPattern(Instruction *I, RecurKind Kind,
690690
return InstDesc(Kind == RecurKind::SMax, I);
691691
if (match(I, m_SMin(m_Value(), m_Value())))
692692
return InstDesc(Kind == RecurKind::SMin, I);
693-
if (match(I, m_OrdFMin(m_Value(), m_Value())))
693+
if (match(I, m_OrdOrUnordFMin(m_Value(), m_Value())))
694694
return InstDesc(Kind == RecurKind::FMin, I);
695-
if (match(I, m_OrdFMax(m_Value(), m_Value())))
696-
return InstDesc(Kind == RecurKind::FMax, I);
697-
if (match(I, m_UnordFMin(m_Value(), m_Value())))
698-
return InstDesc(Kind == RecurKind::FMin, I);
699-
if (match(I, m_UnordFMax(m_Value(), m_Value())))
695+
if (match(I, m_OrdOrUnordFMax(m_Value(), m_Value())))
700696
return InstDesc(Kind == RecurKind::FMax, I);
701697
if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_Value())))
702698
return InstDesc(Kind == RecurKind::FMin, I);

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8240,19 +8240,15 @@ static SelectPatternResult matchFastFloatClamp(CmpInst::Predicate Pred,
82408240
case CmpInst::FCMP_OLE:
82418241
case CmpInst::FCMP_ULT:
82428242
case CmpInst::FCMP_ULE:
8243-
if (match(FalseVal,
8244-
m_CombineOr(m_OrdFMin(m_Specific(CmpLHS), m_APFloat(FC2)),
8245-
m_UnordFMin(m_Specific(CmpLHS), m_APFloat(FC2)))) &&
8243+
if (match(FalseVal, m_OrdOrUnordFMin(m_Specific(CmpLHS), m_APFloat(FC2))) &&
82468244
*FC1 < *FC2)
82478245
return {SPF_FMAXNUM, SPNB_RETURNS_ANY, false};
82488246
break;
82498247
case CmpInst::FCMP_OGT:
82508248
case CmpInst::FCMP_OGE:
82518249
case CmpInst::FCMP_UGT:
82528250
case CmpInst::FCMP_UGE:
8253-
if (match(FalseVal,
8254-
m_CombineOr(m_OrdFMax(m_Specific(CmpLHS), m_APFloat(FC2)),
8255-
m_UnordFMax(m_Specific(CmpLHS), m_APFloat(FC2)))) &&
8251+
if (match(FalseVal, m_OrdOrUnordFMax(m_Specific(CmpLHS), m_APFloat(FC2))) &&
82568252
*FC1 > *FC2)
82578253
return {SPF_FMINNUM, SPNB_RETURNS_ANY, false};
82588254
break;

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,13 +3834,11 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
38343834
// minnum/maxnum intrinsics.
38353835
if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
38363836
Value *X, *Y;
3837-
if (match(&SI, m_OrdFMax(m_Value(X), m_Value(Y))) ||
3838-
match(&SI, m_UnordFMax(m_Value(X), m_Value(Y))))
3837+
if (match(&SI, m_OrdOrUnordFMax(m_Value(X), m_Value(Y))))
38393838
return replaceInstUsesWith(
38403839
SI, Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI));
38413840

3842-
if (match(&SI, m_OrdFMin(m_Value(X), m_Value(Y))) ||
3843-
match(&SI, m_UnordFMin(m_Value(X), m_Value(Y))))
3841+
if (match(&SI, m_OrdOrUnordFMin(m_Value(X), m_Value(Y))))
38443842
return replaceInstUsesWith(
38453843
SI, Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI));
38463844
}

llvm/unittests/IR/PatternMatch.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,140 @@ TEST_F(PatternMatchTest, FloatingPointUnorderedMax) {
10401040
EXPECT_EQ(R, MatchR);
10411041
}
10421042

1043+
TEST_F(PatternMatchTest, FloatingPointMin) {
1044+
Type *FltTy = IRB.getFloatTy();
1045+
Value *L = ConstantFP::get(FltTy, 1.0);
1046+
Value *R = ConstantFP::get(FltTy, 2.0);
1047+
Value *MatchL, *MatchR;
1048+
1049+
// Test OLT.
1050+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1051+
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
1052+
EXPECT_EQ(L, MatchL);
1053+
EXPECT_EQ(R, MatchR);
1054+
1055+
// Test OLE.
1056+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1057+
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
1058+
EXPECT_EQ(L, MatchL);
1059+
EXPECT_EQ(R, MatchR);
1060+
1061+
// Test ULT.
1062+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1063+
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
1064+
EXPECT_EQ(L, MatchL);
1065+
EXPECT_EQ(R, MatchR);
1066+
1067+
// Test ULE.
1068+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1069+
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
1070+
EXPECT_EQ(L, MatchL);
1071+
EXPECT_EQ(R, MatchR);
1072+
1073+
// Test no match on OGE.
1074+
EXPECT_FALSE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1075+
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
1076+
1077+
// Test no match on OGT.
1078+
EXPECT_FALSE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1079+
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
1080+
1081+
// Test no match on UGE.
1082+
EXPECT_FALSE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1083+
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
1084+
1085+
// Test no match on UGT.
1086+
EXPECT_FALSE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1087+
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
1088+
1089+
// Test inverted selects. Note, that this "inverts" the ordering, e.g.:
1090+
// %cmp = fcmp oge L, R
1091+
// %min = select %cmp R, L
1092+
1093+
// [OU]GE with inverted select.
1094+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1095+
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
1096+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1097+
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
1098+
EXPECT_EQ(L, MatchL);
1099+
EXPECT_EQ(R, MatchR);
1100+
1101+
// [OU]GT with inverted select.
1102+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1103+
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
1104+
EXPECT_TRUE(m_OrdOrUnordFMin(m_Value(MatchL), m_Value(MatchR))
1105+
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
1106+
EXPECT_EQ(L, MatchL);
1107+
EXPECT_EQ(R, MatchR);
1108+
}
1109+
1110+
TEST_F(PatternMatchTest, FloatingPointMax) {
1111+
Type *FltTy = IRB.getFloatTy();
1112+
Value *L = ConstantFP::get(FltTy, 1.0);
1113+
Value *R = ConstantFP::get(FltTy, 2.0);
1114+
Value *MatchL, *MatchR;
1115+
1116+
// Test OGT.
1117+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1118+
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
1119+
EXPECT_EQ(L, MatchL);
1120+
EXPECT_EQ(R, MatchR);
1121+
1122+
// Test OGE.
1123+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1124+
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
1125+
EXPECT_EQ(L, MatchL);
1126+
EXPECT_EQ(R, MatchR);
1127+
1128+
// Test UGT.
1129+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1130+
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
1131+
EXPECT_EQ(L, MatchL);
1132+
EXPECT_EQ(R, MatchR);
1133+
1134+
// Test UGE.
1135+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1136+
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
1137+
EXPECT_EQ(L, MatchL);
1138+
EXPECT_EQ(R, MatchR);
1139+
1140+
// Test no match on OLE.
1141+
EXPECT_FALSE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1142+
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
1143+
1144+
// Test no match on OLT.
1145+
EXPECT_FALSE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1146+
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
1147+
1148+
// Test no match on ULE.
1149+
EXPECT_FALSE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1150+
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
1151+
1152+
// Test no match on ULT.
1153+
EXPECT_FALSE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1154+
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
1155+
1156+
// Test inverted selects. Note, that this "inverts" the ordering, e.g.:
1157+
// %cmp = fcmp ole L, R
1158+
// %max = select %cmp, R, L
1159+
1160+
// [OU]LE with inverted select.
1161+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1162+
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
1163+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1164+
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
1165+
EXPECT_EQ(L, MatchL);
1166+
EXPECT_EQ(R, MatchR);
1167+
1168+
// [OUT]LT with inverted select.
1169+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1170+
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
1171+
EXPECT_TRUE(m_OrdOrUnordFMax(m_Value(MatchL), m_Value(MatchR))
1172+
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
1173+
EXPECT_EQ(L, MatchL);
1174+
EXPECT_EQ(R, MatchR);
1175+
}
1176+
10431177
TEST_F(PatternMatchTest, OverflowingBinOps) {
10441178
Value *L = IRB.getInt32(1);
10451179
Value *R = IRB.getInt32(2);

0 commit comments

Comments
 (0)