return m_Intrinsic<Intrinsic::maxnum>(Op0, Op1);
}
+template <typename Opnd0, typename Opnd1, typename Opnd2>
+inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
+m_FShl(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
+ return m_Intrinsic<Intrinsic::fshl>(Op0, Op1, Op2);
+}
+
+template <typename Opnd0, typename Opnd1, typename Opnd2>
+inline typename m_Intrinsic_Ty<Opnd0, Opnd1, Opnd2>::Ty
+m_FShr(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2) {
+ return m_Intrinsic<Intrinsic::fshr>(Op0, Op1, Op2);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for two-operands operators with the operators in either order
//
// Test for a bogus zero-shift-guard-op around funnel-shift or rotate.
Value *ShAmt;
- auto isFsh = m_CombineOr(m_Intrinsic<Intrinsic::fshl>(m_Value(X), m_Value(),
- m_Value(ShAmt)),
- m_Intrinsic<Intrinsic::fshr>(m_Value(), m_Value(X),
- m_Value(ShAmt)));
+ auto isFsh = m_CombineOr(m_FShl(m_Value(X), m_Value(), m_Value(ShAmt)),
+ m_FShr(m_Value(), m_Value(X), m_Value(ShAmt)));
// (ShAmt == 0) ? fshl(X, *, ShAmt) : X --> X
// (ShAmt == 0) ? fshr(*, X, ShAmt) : X --> X
if (match(TrueVal, isFsh) && FalseVal == X && CmpLHS == ShAmt)
// intrinsics do not have that problem.
// We do not allow this transform for the general funnel shift case because
// that would not preserve the poison safety of the original code.
- auto isRotate = m_CombineOr(m_Intrinsic<Intrinsic::fshl>(m_Value(X),
- m_Deferred(X),
- m_Value(ShAmt)),
- m_Intrinsic<Intrinsic::fshr>(m_Value(X),
- m_Deferred(X),
- m_Value(ShAmt)));
+ auto isRotate =
+ m_CombineOr(m_FShl(m_Value(X), m_Deferred(X), m_Value(ShAmt)),
+ m_FShr(m_Value(X), m_Deferred(X), m_Value(ShAmt)));
// (ShAmt == 0) ? X : fshl(X, X, ShAmt) --> fshl(X, X, ShAmt)
// (ShAmt == 0) ? X : fshr(X, X, ShAmt) --> fshr(X, X, ShAmt)
if (match(FalseVal, isRotate) && TrueVal == X && CmpLHS == ShAmt &&