[llvm] [AArch64][SVE] Use ADD/ADR instead of MUL/MLA for x*N (PR #198566)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 05:09:05 PDT 2026
================
@@ -1948,6 +1948,75 @@ let Predicates = [HasSVE] in {
defm : adrShiftPat<nxv4i32, nxv4i1, i32, ADR_LSL_ZZZ_S_2, 2>;
defm : adrShiftPat<nxv4i32, nxv4i1, i32, ADR_LSL_ZZZ_S_3, 3>;
+ // Avoid MUL/MLA for small constants where ADD/ADR forms are available.
+ multiclass sveMulImmAddAdrPat<ValueType Ty, ValueType PredTy,
+ ValueType ScalarTy, Instruction Add,
+ Instruction Adr1, Instruction Adr2,
+ Instruction Adr3> {
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)), Ty:$Op,
+ (Ty (splat_vector (ScalarTy 2))))),
+ (Add $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)), Ty:$Op,
+ (Ty (splat_vector (ScalarTy 3))))),
+ (Adr1 $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)), Ty:$Op,
+ (Ty (splat_vector (ScalarTy 5))))),
+ (Adr2 $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)), Ty:$Op,
+ (Ty (splat_vector (ScalarTy 9))))),
+ (Adr3 $Op, $Op)>;
+
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)),
+ (Ty (splat_vector (ScalarTy 2))), Ty:$Op)),
+ (Add $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)),
+ (Ty (splat_vector (ScalarTy 3))), Ty:$Op)),
+ (Adr1 $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)),
+ (Ty (splat_vector (ScalarTy 5))), Ty:$Op)),
+ (Adr2 $Op, $Op)>;
+ def : Pat<(Ty (AArch64mul_p (PredTy (SVEAnyPredicate)),
+ (Ty (splat_vector (ScalarTy 9))), Ty:$Op)),
+ (Adr3 $Op, $Op)>;
----------------
paulwalker-arm wrote:
These can be dropped because we should be canonicalising constants to the RHS. For the ACLE intrinsics this is done by `simplifySVEIntrinsicBinOp`.
https://github.com/llvm/llvm-project/pull/198566
More information about the llvm-commits
mailing list