diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -684,6 +684,36 @@ return None; } +static Optional instCombineSVEVectorBinOp(InstCombiner &IC, + IntrinsicInst &II) { + auto *OpPredicate = II.getOperand(0); + auto *OpMultiplicand = II.getOperand(1); + auto *OpMultiplier = II.getOperand(2); + + IRBuilder<> Builder(II.getContext()); + Builder.SetInsertPoint(&II); + + auto IsIntrinsic = [](auto *I, auto In) { + auto *IntrI = dyn_cast(I); + if (!IntrI || IntrI->getIntrinsicID() != In) + return false; + return true; + }; + + if (IsIntrinsic(&II, Intrinsic::aarch64_sve_fmul) && + IsIntrinsic(OpPredicate, Intrinsic::aarch64_sve_convert_from_svbool)) { + return IC.replaceInstUsesWith( + II, Builder.CreateFMul(OpMultiplicand, OpMultiplier)); + } else if (IsIntrinsic(&II, Intrinsic::aarch64_sve_fadd) && + IsIntrinsic(OpPredicate, + Intrinsic::aarch64_sve_convert_from_svbool)) { + return IC.replaceInstUsesWith( + II, Builder.CreateFAdd(OpMultiplicand, OpMultiplier)); + } + + return None; +} + static Optional instCombineSVEVectorMul(InstCombiner &IC, IntrinsicInst &II) { auto *OpPredicate = II.getOperand(0); @@ -736,7 +766,7 @@ } } - return None; + return instCombineSVEVectorBinOp(IC, II); } static Optional instCombineSVEUnpack(InstCombiner &IC, @@ -824,6 +854,8 @@ case Intrinsic::aarch64_sve_mul: case Intrinsic::aarch64_sve_fmul: return instCombineSVEVectorMul(IC, II); + case Intrinsic::aarch64_sve_fadd: + return instCombineSVEVectorBinOp(IC, II); case Intrinsic::aarch64_sve_tbl: return instCombineSVETBL(IC, II); case Intrinsic::aarch64_sve_uunpkhi: