diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index cded28054f5925..d8a0e68d712375 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 b0f059c9de605e..c6f08ce8288266 100644 --- a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll @@ -12,6 +12,16 @@ define @replace_sel_intrinsic( %p, %1 } +define @sel_ptrue( %a, %b) { +; CHECK-LABEL: @sel_ptrue( +; CHECK-NEXT: ret [[A:%.*]] +; + %pred = call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) + %res = call @llvm.aarch64.sve.sel.nxv4i32( %pred, %a, %b) + ret %res +} + +declare @llvm.aarch64.sve.ptrue.nxv4i1(i32) declare @llvm.aarch64.sve.sel.nxv4i32(, , ) attributes #0 = { "target-features"="+sve" }