From 831e1ac12e766ae8c94d8d735d8f32c8d319e576 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Thu, 26 Dec 2024 09:28:17 -0800 Subject: [PATCH] [MIPatternMatch] Add m_GUMin and m_GUMax (#121068) And make all unsigned and signed versions of min/max matchers commutative, since we already made a precedent of m_GAdd that is commutative by default. --- .../llvm/CodeGen/GlobalISel/MIPatternMatch.h | 20 +++++++++++--- .../CodeGen/GlobalISel/PatternMatchTest.cpp | 26 +++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index 80d1fef7533c..47417f53b6e4 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -538,15 +538,27 @@ m_GAShr(const LHS &L, const RHS &R) { } template -inline BinaryOp_match +inline BinaryOp_match m_GSMax(const LHS &L, const RHS &R) { - return BinaryOp_match(L, R); + return BinaryOp_match(L, R); } template -inline BinaryOp_match +inline BinaryOp_match m_GSMin(const LHS &L, const RHS &R) { - return BinaryOp_match(L, R); + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match +m_GUMax(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); +} + +template +inline BinaryOp_match +m_GUMin(const LHS &L, const RHS &R) { + return BinaryOp_match(L, R); } // Helper for unary instructions (G_[ZSA]EXT/G_TRUNC) etc diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp index bcaa321e49c1..fc76d4055722 100644 --- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -224,6 +224,32 @@ TEST_F(AArch64GISelMITest, MatchBinaryOp) { auto MIBAddCst = B.buildAdd(s64, MIBCst, Copies[0]); auto MIBUnmerge = B.buildUnmerge({s32, s32}, B.buildConstant(s64, 42)); + // Match min/max, and make sure they're commutative. + auto SMin = B.buildSMin(s64, Copies[2], MIBAdd); + EXPECT_TRUE(mi_match(SMin.getReg(0), *MRI, + m_GSMin(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0)))); + EXPECT_EQ(Src0, Copies[2]); + EXPECT_EQ(Src1, Copies[0]); + EXPECT_EQ(Src2, Copies[1]); + auto SMax = B.buildSMax(s64, Copies[2], MIBAdd); + EXPECT_TRUE(mi_match(SMax.getReg(0), *MRI, + m_GSMax(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0)))); + EXPECT_EQ(Src0, Copies[2]); + EXPECT_EQ(Src1, Copies[0]); + EXPECT_EQ(Src2, Copies[1]); + auto UMin = B.buildUMin(s64, Copies[2], MIBAdd); + EXPECT_TRUE(mi_match(UMin.getReg(0), *MRI, + m_GUMin(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0)))); + EXPECT_EQ(Src0, Copies[2]); + EXPECT_EQ(Src1, Copies[0]); + EXPECT_EQ(Src2, Copies[1]); + auto UMax = B.buildUMax(s64, Copies[2], MIBAdd); + EXPECT_TRUE(mi_match(UMax.getReg(0), *MRI, + m_GUMax(m_GAdd(m_Reg(Src1), m_Reg(Src2)), m_Reg(Src0)))); + EXPECT_EQ(Src0, Copies[2]); + EXPECT_EQ(Src1, Copies[0]); + EXPECT_EQ(Src2, Copies[1]); + // m_BinOp with opcode. // Match binary instruction, opcode and its non-commutative operands. match = mi_match(MIBAddCst, *MRI,