[llvm] 509ee6b - [PatternMatch] Fix matching order for `m_c_Intrinsic` (#166047)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 6 09:52:57 PST 2025
Author: Yingwei Zheng
Date: 2025-11-07T01:52:53+08:00
New Revision: 509ee6baa6f463b6c69099cc97a195614cf8382a
URL: https://github.com/llvm/llvm-project/commit/509ee6baa6f463b6c69099cc97a195614cf8382a
DIFF: https://github.com/llvm/llvm-project/commit/509ee6baa6f463b6c69099cc97a195614cf8382a.diff
LOG: [PatternMatch] Fix matching order for `m_c_Intrinsic` (#166047)
`Op0` should always be checked before `Op1`. Otherwise it may not work
as expected when `Op1` contains `m_Deferred`.
Added:
Modified:
llvm/include/llvm/IR/PatternMatch.h
llvm/unittests/IR/PatternMatch.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index e3ec7e1764da7..bb3d7fff5c9bc 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -3069,12 +3069,26 @@ m_c_MaxOrMin(const LHS &L, const RHS &R) {
m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R)));
}
+template <Intrinsic::ID IntrID, typename LHS, typename RHS>
+struct CommutativeBinaryIntrinsic_match {
+ LHS L;
+ RHS R;
+
+ CommutativeBinaryIntrinsic_match(const LHS &L, const RHS &R) : L(L), R(R) {}
+
+ template <typename OpTy> bool match(OpTy *V) const {
+ const auto *II = dyn_cast<IntrinsicInst>(V);
+ if (!II || II->getIntrinsicID() != IntrID)
+ return false;
+ return (L.match(II->getArgOperand(0)) && R.match(II->getArgOperand(1))) ||
+ (L.match(II->getArgOperand(1)) && R.match(II->getArgOperand(0)));
+ }
+};
+
template <Intrinsic::ID IntrID, typename T0, typename T1>
-inline match_combine_or<typename m_Intrinsic_Ty<T0, T1>::Ty,
- typename m_Intrinsic_Ty<T1, T0>::Ty>
+inline CommutativeBinaryIntrinsic_match<IntrID, T0, T1>
m_c_Intrinsic(const T0 &Op0, const T1 &Op1) {
- return m_CombineOr(m_Intrinsic<IntrID>(Op0, Op1),
- m_Intrinsic<IntrID>(Op1, Op0));
+ return CommutativeBinaryIntrinsic_match<IntrID, T0, T1>(Op0, Op1);
}
/// Matches FAdd with LHS and RHS in either order.
diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp
index 972dac82d3331..1142c559c97f8 100644
--- a/llvm/unittests/IR/PatternMatch.cpp
+++ b/llvm/unittests/IR/PatternMatch.cpp
@@ -2657,4 +2657,31 @@ TEST_F(PatternMatchTest, ShiftOrSelf) {
EXPECT_EQ(ShAmtC, 0U);
}
+TEST_F(PatternMatchTest, CommutativeDeferredIntrinsicMatch) {
+ Value *X = ConstantFP::get(IRB.getDoubleTy(), 1.0);
+ Value *Y = ConstantFP::get(IRB.getDoubleTy(), 2.0);
+
+ auto CheckMatch = [X, Y](Value *Pattern) {
+ Value *tX = nullptr, *tY = nullptr;
+ EXPECT_TRUE(
+ match(Pattern, m_c_Intrinsic<Intrinsic::minimum>(
+ m_Value(tX), m_c_Intrinsic<Intrinsic::minimum>(
+ m_Deferred(tX), m_Value(tY)))));
+ EXPECT_EQ(tX, X);
+ EXPECT_EQ(tY, Y);
+ };
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, X,
+ IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y)));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, X,
+ IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X)));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, X, Y),
+ X));
+ CheckMatch(IRB.CreateBinaryIntrinsic(
+ Intrinsic::minimum, IRB.CreateBinaryIntrinsic(Intrinsic::minimum, Y, X),
+ X));
+}
+
} // anonymous namespace.
More information about the llvm-commits
mailing list