diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -191,6 +191,18 @@ Pred = ICmpInst::getSwappedPredicate(Pred); } + // Check for inverted variants of min/max by swapping operands. + switch (Pred) { + case CmpInst::ICMP_ULE: + case CmpInst::ICMP_UGE: + case CmpInst::ICMP_SLE: + case CmpInst::ICMP_SGE: + Pred = CmpInst::getInversePredicate(Pred); + std::swap(A, B); + default: + break; + } + switch (Pred) { case CmpInst::ICMP_UGT: Flavor = SPF_UMAX; break; case CmpInst::ICMP_ULT: Flavor = SPF_UMIN; break; @@ -257,6 +269,25 @@ Value *X, *Y; if (!match(Cond, m_Cmp(Pred, m_Value(X), m_Value(Y)))) return hash_combine(Inst->getOpcode(), Cond, A, B); +#if 0 + // Prefer to hash the select as a min/max if possible. + CmpInst::Predicate InvPred = CmpInst::getInversePredicate(Pred); + if (X == B && Y == A) { + switch (InvPred) { + case CmpInst::ICMP_UGT: SPF = SPF_UMAX; break; + case CmpInst::ICMP_ULT: SPF = SPF_UMIN; break; + case CmpInst::ICMP_SGT: SPF = SPF_SMAX; break; + case CmpInst::ICMP_SLT: SPF = SPF_SMIN; break; + default: break; + } + if (SPF == SPF_SMIN || SPF == SPF_SMAX || + SPF == SPF_UMIN || SPF == SPF_UMAX) { + if (A > B) + std::swap(A, B); + return hash_combine(Inst->getOpcode(), SPF, A, B); + } + } +#endif // Similar to cmp normalization (above) - canonicalize the predicate value: // select (icmp Pred, X, Y), A, B --> select (icmp InvPred, X, Y), B, A