From 2334872d26b1557019c513f07dd3dc620e1429e7 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sun, 2 Nov 2025 15:55:45 +0800 Subject: [PATCH 1/2] [PatternMatch] Fix matching order for --- llvm/include/llvm/IR/PatternMatch.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index e3ec7e1764da7..54f9c28dcbf97 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -3069,12 +3069,28 @@ m_c_MaxOrMin(const LHS &L, const RHS &R) { m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R))); } +template +struct CommutativeBinaryIntrinsic_match { + unsigned ID; + LHS L; + RHS R; + + CommutativeBinaryIntrinsic_match(const LHS &L, const RHS &R) + : ID(IntrID), L(L), R(R) {} + + template bool match(OpTy *V) const { + const auto *II = dyn_cast(V); + if (!II || II->getIntrinsicID() != ID) + return false; + return (L.match(II->getArgOperand(0)) && R.match(II->getArgOperand(1))) || + (L.match(II->getArgOperand(1)) && R.match(II->getArgOperand(0))); + } +}; + template -inline match_combine_or::Ty, - typename m_Intrinsic_Ty::Ty> +inline CommutativeBinaryIntrinsic_match m_c_Intrinsic(const T0 &Op0, const T1 &Op1) { - return m_CombineOr(m_Intrinsic(Op0, Op1), - m_Intrinsic(Op1, Op0)); + return CommutativeBinaryIntrinsic_match(Op0, Op1); } /// Matches FAdd with LHS and RHS in either order. From c9de923a34e608ce2dfbda94757266367cf96901 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Fri, 7 Nov 2025 00:08:41 +0800 Subject: [PATCH 2/2] [PatternMatch] Add a unit test --- llvm/include/llvm/IR/PatternMatch.h | 6 ++---- llvm/unittests/IR/PatternMatch.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 54f9c28dcbf97..bb3d7fff5c9bc 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -3071,16 +3071,14 @@ m_c_MaxOrMin(const LHS &L, const RHS &R) { template struct CommutativeBinaryIntrinsic_match { - unsigned ID; LHS L; RHS R; - CommutativeBinaryIntrinsic_match(const LHS &L, const RHS &R) - : ID(IntrID), L(L), R(R) {} + CommutativeBinaryIntrinsic_match(const LHS &L, const RHS &R) : L(L), R(R) {} template bool match(OpTy *V) const { const auto *II = dyn_cast(V); - if (!II || II->getIntrinsicID() != ID) + 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))); 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( + m_Value(tX), m_c_Intrinsic( + 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.