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 @@ -258,6 +258,24 @@ if (!match(Cond, m_Cmp(Pred, m_Value(X), m_Value(Y)))) return hash_combine(Inst->getOpcode(), Cond, A, B); + // 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); + } + } + // Similar to cmp normalization (above) - canonicalize the predicate value: // select (icmp Pred, X, Y), A, B --> select (icmp InvPred, X, Y), B, A if (CmpInst::getInversePredicate(Pred) < Pred) {