From bf90ffb9b4617297053ce7228474e224922f2391 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Wed, 27 Sep 2023 22:42:43 -0400 Subject: [PATCH] [SVE][InstCombine] Delete redundante sel instructions with ptrue svsel(pture, x, y) => x. depend on D121792 Reviewed By: paulwalker-arm, david-arm --- .../AArch64/AArch64TargetTransformInfo.cpp | 41 +++++++++++-------- .../InstCombine/AArch64/sve-intrinsic-sel.ll | 4 +- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index cded28054f592..d8a0e68d71237 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -798,10 +798,31 @@ instCombineConvertFromSVBool(InstCombiner &IC, IntrinsicInst &II) { return IC.replaceInstUsesWith(II, EarliestReplacement); } +static bool isAllActivePredicate(Value *Pred) { + // Look through convert.from.svbool(convert.to.svbool(...) chain. + Value *UncastedPred; + if (match(Pred, m_Intrinsic( + m_Intrinsic( + m_Value(UncastedPred))))) + // If the predicate has the same or less lanes than the uncasted + // predicate then we know the casting has no effect. + if (cast(Pred->getType())->getMinNumElements() <= + cast(UncastedPred->getType())->getMinNumElements()) + Pred = UncastedPred; + + return match(Pred, m_Intrinsic( + m_ConstantInt())); +} + static std::optional instCombineSVESel(InstCombiner &IC, IntrinsicInst &II) { - auto Select = IC.Builder.CreateSelect(II.getOperand(0), II.getOperand(1), - II.getOperand(2)); + // svsel(ptrue, x, y) => x + auto *OpPredicate = II.getOperand(0); + if (isAllActivePredicate(OpPredicate)) + return IC.replaceInstUsesWith(II, II.getOperand(1)); + + auto Select = + IC.Builder.CreateSelect(OpPredicate, II.getOperand(1), II.getOperand(2)); return IC.replaceInstUsesWith(II, Select); } @@ -1200,22 +1221,6 @@ instCombineSVEVectorFuseMulAddSub(InstCombiner &IC, IntrinsicInst &II, return IC.replaceInstUsesWith(II, Res); } -static bool isAllActivePredicate(Value *Pred) { - // Look through convert.from.svbool(convert.to.svbool(...) chain. - Value *UncastedPred; - if (match(Pred, m_Intrinsic( - m_Intrinsic( - m_Value(UncastedPred))))) - // If the predicate has the same or less lanes than the uncasted - // predicate then we know the casting has no effect. - if (cast(Pred->getType())->getMinNumElements() <= - cast(UncastedPred->getType())->getMinNumElements()) - Pred = UncastedPred; - - return match(Pred, m_Intrinsic( - m_ConstantInt())); -} - static std::optional instCombineSVELD1(InstCombiner &IC, IntrinsicInst &II, const DataLayout &DL) { Value *Pred = II.getOperand(0); diff --git a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll index 0d0c3b9892758..c6f08ce828826 100644 --- a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll @@ -14,9 +14,7 @@ define @replace_sel_intrinsic( %p, @sel_ptrue( %a, %b) { ; CHECK-LABEL: @sel_ptrue( -; CHECK-NEXT: [[PRED:%.*]] = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) -; CHECK-NEXT: [[RES:%.*]] = select [[PRED]], [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: ret [[RES]] +; CHECK-NEXT: ret [[A:%.*]] ; %pred = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %res = call @llvm.aarch64.sve.sel.nxv4i32( %pred, %a, %b)