Skip to content

Commit d012642

Browse files
authored
[VPlan] Match more GEP-like in m_GetElementPtr (#158019)
The m_GetElementPtr matcher is incorrect and incomplete. Fix it to match all possible GEPs to avoid misleading users. It currently just has one use, and the change is non-functional for that use.
1 parent 27b242f commit d012642

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,9 @@ class LLVM_ABI_FOR_TEST VPWidenGEPRecipe : public VPRecipeWithIRFlags {
17951795

17961796
VP_CLASSOF_IMPL(VPDef::VPWidenGEPSC)
17971797

1798+
/// This recipe generates a GEP instruction.
1799+
unsigned getOpcode() const { return Instruction::GetElementPtr; }
1800+
17981801
/// Generate the gep nodes.
17991802
void execute(VPTransformState &State) override;
18001803

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,9 @@ struct Recipe_match {
260260
static bool matchRecipeAndOpcode(const VPRecipeBase *R) {
261261
auto *DefR = dyn_cast<RecipeTy>(R);
262262
// Check for recipes that do not have opcodes.
263-
if constexpr (std::is_same<RecipeTy, VPScalarIVStepsRecipe>::value ||
264-
std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value ||
265-
std::is_same<RecipeTy, VPDerivedIVRecipe>::value ||
266-
std::is_same<RecipeTy, VPWidenGEPRecipe>::value)
263+
if constexpr (std::is_same_v<RecipeTy, VPScalarIVStepsRecipe> ||
264+
std::is_same_v<RecipeTy, VPCanonicalIVPHIRecipe> ||
265+
std::is_same_v<RecipeTy, VPDerivedIVRecipe>)
267266
return DefR;
268267
else
269268
return DefR && DefR->getOpcode() == Opcode;
@@ -532,15 +531,24 @@ m_SpecificCmp(CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
532531
}
533532

534533
template <typename Op0_t, typename Op1_t>
535-
using GEPLikeRecipe_match =
534+
using GEPLikeRecipe_match = match_combine_or<
536535
Recipe_match<std::tuple<Op0_t, Op1_t>, Instruction::GetElementPtr,
537-
/*Commutative*/ false, VPWidenRecipe, VPReplicateRecipe,
538-
VPWidenGEPRecipe, VPInstruction>;
536+
/*Commutative*/ false, VPReplicateRecipe, VPWidenGEPRecipe>,
537+
match_combine_or<
538+
VPInstruction_match<VPInstruction::PtrAdd, Op0_t, Op1_t>,
539+
VPInstruction_match<VPInstruction::WidePtrAdd, Op0_t, Op1_t>>>;
539540

540541
template <typename Op0_t, typename Op1_t>
541542
inline GEPLikeRecipe_match<Op0_t, Op1_t> m_GetElementPtr(const Op0_t &Op0,
542543
const Op1_t &Op1) {
543-
return GEPLikeRecipe_match<Op0_t, Op1_t>(Op0, Op1);
544+
return m_CombineOr(
545+
Recipe_match<std::tuple<Op0_t, Op1_t>, Instruction::GetElementPtr,
546+
/*Commutative*/ false, VPReplicateRecipe, VPWidenGEPRecipe>(
547+
Op0, Op1),
548+
m_CombineOr(
549+
VPInstruction_match<VPInstruction::PtrAdd, Op0_t, Op1_t>(Op0, Op1),
550+
VPInstruction_match<VPInstruction::WidePtrAdd, Op0_t, Op1_t>(Op0,
551+
Op1)));
544552
}
545553

546554
template <typename Op0_t, typename Op1_t, typename Op2_t>

llvm/unittests/Transforms/Vectorize/VPlanPatternMatchTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,29 @@ TEST_F(VPPatternMatchTest, ScalarIVSteps) {
5151
m_SpecificInt(2), m_Specific(VF))));
5252
}
5353

54+
TEST_F(VPPatternMatchTest, GetElementPtr) {
55+
VPlan &Plan = getPlan();
56+
VPBasicBlock *VPBB = Plan.createVPBasicBlock("entry");
57+
VPBuilder Builder(VPBB);
58+
59+
IntegerType *I64Ty = IntegerType::get(C, 64);
60+
VPValue *One = Plan.getOrAddLiveIn(ConstantInt::get(I64Ty, 1));
61+
VPValue *Two = Plan.getOrAddLiveIn(ConstantInt::get(I64Ty, 2));
62+
VPValue *Ptr =
63+
Plan.getOrAddLiveIn(Constant::getNullValue(PointerType::get(C, 0)));
64+
65+
VPInstruction *PtrAdd = Builder.createPtrAdd(Ptr, One);
66+
VPInstruction *WidePtrAdd = Builder.createWidePtrAdd(Ptr, Two);
67+
68+
using namespace VPlanPatternMatch;
69+
ASSERT_TRUE(
70+
match(PtrAdd, m_GetElementPtr(m_Specific(Ptr), m_SpecificInt(1))));
71+
ASSERT_FALSE(
72+
match(PtrAdd, m_GetElementPtr(m_Specific(Ptr), m_SpecificInt(2))));
73+
ASSERT_TRUE(
74+
match(WidePtrAdd, m_GetElementPtr(m_Specific(Ptr), m_SpecificInt(2))));
75+
ASSERT_FALSE(
76+
match(WidePtrAdd, m_GetElementPtr(m_Specific(Ptr), m_SpecificInt(1))));
77+
}
5478
} // namespace
5579
} // namespace llvm

0 commit comments

Comments
 (0)