[llvm] [AArch64][SVE] Use ADD/ADR instead of MUL/MLA for x*N (PR #198566)

Tomas Matheson via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 08:31:52 PDT 2026


https://github.com/tommat01 updated https://github.com/llvm/llvm-project/pull/198566

>From f4634a2e94e50e4e08f54abdbc552beb6e85f5c4 Mon Sep 17 00:00:00 2001
From: Tomas Matheson <tomas.matheson at arm.com>
Date: Fri, 5 Jun 2026 18:36:22 +0100
Subject: [PATCH] [AArch64][SVE] Use ADD/ADR instead of MUL/MLA for x*N

---
 .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 115 +++++++++
 .../AArch64/sve-intrinsics-int-arith-undef.ll |   2 +-
 .../CodeGen/AArch64/sve-mul-imm-add-adr.ll    | 242 ++++++++++++++++++
 llvm/test/CodeGen/AArch64/sve2-histcnt.ll     |   4 +-
 4 files changed, 359 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/sve-mul-imm-add-adr.ll

diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 0cc788d12bae0..1aa12130cf36d 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -1948,6 +1948,121 @@ 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_m1 (PredTy (SVEAllActive)), Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 2))))),
+              (Add $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)), Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 3))))),
+              (Adr1 $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)), Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 5))))),
+              (Adr2 $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)), Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 9))))),
+              (Adr3 $Op, $Op)>;
+
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)),
+                                  (Ty (splat_vector (ScalarTy 2))), Ty:$Op)),
+              (Add $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)),
+                                  (Ty (splat_vector (ScalarTy 3))), Ty:$Op)),
+              (Adr1 $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)),
+                                  (Ty (splat_vector (ScalarTy 5))), Ty:$Op)),
+              (Adr2 $Op, $Op)>;
+    def : Pat<(Ty (AArch64mul_m1 (PredTy (SVEAllActive)),
+                                  (Ty (splat_vector (ScalarTy 9))), Ty:$Op)),
+              (Adr3 $Op, $Op)>;
+
+    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)>;
+  }
+
+  multiclass sveMlaImmAdrPat<ValueType Ty, ValueType PredTy,
+                             ValueType ScalarTy, Instruction Adr1,
+                             Instruction Adr2, Instruction Adr3> {
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc, Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 2))))),
+              (Adr1 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc, Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 4))))),
+              (Adr2 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc, Ty:$Op,
+                                  (Ty (splat_vector (ScalarTy 8))))),
+              (Adr3 $Acc, $Op)>;
+
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc,
+                                  (Ty (splat_vector (ScalarTy 2))), Ty:$Op)),
+              (Adr1 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc,
+                                  (Ty (splat_vector (ScalarTy 4))), Ty:$Op)),
+              (Adr2 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_m1 (PredTy (SVEAllActive)), Ty:$Acc,
+                                  (Ty (splat_vector (ScalarTy 8))), Ty:$Op)),
+              (Adr3 $Acc, $Op)>;
+
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc, Ty:$Op,
+                                (Ty (splat_vector (ScalarTy 2))))),
+              (Adr1 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc, Ty:$Op,
+                                (Ty (splat_vector (ScalarTy 4))))),
+              (Adr2 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc, Ty:$Op,
+                                (Ty (splat_vector (ScalarTy 8))))),
+              (Adr3 $Acc, $Op)>;
+
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc,
+                                (Ty (splat_vector (ScalarTy 2))), Ty:$Op)),
+              (Adr1 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc,
+                                (Ty (splat_vector (ScalarTy 4))), Ty:$Op)),
+              (Adr2 $Acc, $Op)>;
+    def : Pat<(Ty (AArch64mla_p (PredTy (SVEAnyPredicate)), Ty:$Acc,
+                                (Ty (splat_vector (ScalarTy 8))), Ty:$Op)),
+              (Adr3 $Acc, $Op)>;
+  }
+
+  let AddedComplexity = 10 in {
+    defm : sveMulImmAddAdrPat<nxv2i64, nxv2i1, i64, ADD_ZZZ_D,
+                              ADR_LSL_ZZZ_D_1, ADR_LSL_ZZZ_D_2,
+                              ADR_LSL_ZZZ_D_3>;
+    defm : sveMulImmAddAdrPat<nxv4i32, nxv4i1, i32, ADD_ZZZ_S,
+                              ADR_LSL_ZZZ_S_1, ADR_LSL_ZZZ_S_2,
+                              ADR_LSL_ZZZ_S_3>;
+    defm : sveMlaImmAdrPat<nxv2i64, nxv2i1, i64, ADR_LSL_ZZZ_D_1,
+                           ADR_LSL_ZZZ_D_2, ADR_LSL_ZZZ_D_3>;
+    defm : sveMlaImmAdrPat<nxv4i32, nxv4i1, i32, ADR_LSL_ZZZ_S_1,
+                           ADR_LSL_ZZZ_S_2, ADR_LSL_ZZZ_S_3>;
+  }
+
   // adr z0.d, [z0.d, z0.d, uxtw #<shift>]
   // adr z0.d, [z0.d, z0.d, sxtw #<shift>]
   multiclass adrXtwShiftPat<ValueType Ty, ValueType PredTy, int ShiftAmt> {
diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-undef.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-undef.ll
index 82b39785a07b5..1446f6956cf04 100644
--- a/llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-undef.ll
+++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-undef.ll
@@ -301,7 +301,7 @@ define <vscale x 8 x i16> @mul_imm_i16(<vscale x 8 x i1> %pg, <vscale x 8 x i16>
 define <vscale x 4 x i32> @mul_imm_i32(<vscale x 4 x i1> %pg, <vscale x 4 x i32> %a) {
 ; CHECK-LABEL: mul_imm_i32:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mul z0.s, z0.s, #5
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #2]
 ; CHECK-NEXT:    ret
   %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.u.nxv4i32(<vscale x 4 x i1> %pg,
                                                                  <vscale x 4 x i32> %a,
diff --git a/llvm/test/CodeGen/AArch64/sve-mul-imm-add-adr.ll b/llvm/test/CodeGen/AArch64/sve-mul-imm-add-adr.ll
new file mode 100644
index 0000000000000..02760611b6285
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-mul-imm-add-adr.ll
@@ -0,0 +1,242 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
+
+define <vscale x 4 x i32> @mul_i32_by_2(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: mul_i32_by_2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    lsl z0.s, z0.s, #1
+; CHECK-NEXT:    ret
+  %out = mul <vscale x 4 x i32> %x, splat(i32 2)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @mul_i32_by_3(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: mul_i32_by_3:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #1]
+; CHECK-NEXT:    ret
+  %out = mul <vscale x 4 x i32> %x, splat(i32 3)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @mul_i32_by_5(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: mul_i32_by_5:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #2]
+; CHECK-NEXT:    ret
+  %out = mul <vscale x 4 x i32> %x, splat(i32 5)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @mul_i32_by_9(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: mul_i32_by_9:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #3]
+; CHECK-NEXT:    ret
+  %out = mul <vscale x 4 x i32> %x, splat(i32 9)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 2 x i64> @mul_i64_by_5_commuted(<vscale x 2 x i64> %x) {
+; CHECK-LABEL: mul_i64_by_5_commuted:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.d, [z0.d, z0.d, lsl #2]
+; CHECK-NEXT:    ret
+  %out = mul <vscale x 2 x i64> splat(i64 5), %x
+  ret <vscale x 2 x i64> %out
+}
+
+define <vscale x 4 x i32> @mla_i32_by_2(<vscale x 4 x i32> %a,
+                                        <vscale x 4 x i32> %x) {
+; CHECK-LABEL: mla_i32_by_2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #1]
+; CHECK-NEXT:    ret
+  %mul = mul <vscale x 4 x i32> %x, splat(i32 2)
+  %out = add <vscale x 4 x i32> %a, %mul
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @mla_i32_by_4(<vscale x 4 x i32> %a,
+                                        <vscale x 4 x i32> %x) {
+; CHECK-LABEL: mla_i32_by_4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #2]
+; CHECK-NEXT:    ret
+  %mul = mul <vscale x 4 x i32> %x, splat(i32 4)
+  %out = add <vscale x 4 x i32> %a, %mul
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @mla_i32_by_8(<vscale x 4 x i32> %a,
+                                        <vscale x 4 x i32> %x) {
+; CHECK-LABEL: mla_i32_by_8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #3]
+; CHECK-NEXT:    ret
+  %mul = mul <vscale x 4 x i32> %x, splat(i32 8)
+  %out = add <vscale x 4 x i32> %a, %mul
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 2 x i64> @mla_i64_by_4_commuted(<vscale x 2 x i64> %a,
+                                                 <vscale x 2 x i64> %x) {
+; CHECK-LABEL: mla_i64_by_4_commuted:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.d, [z0.d, z1.d, lsl #2]
+; CHECK-NEXT:    ret
+  %mul = mul <vscale x 2 x i64> splat(i64 4), %x
+  %out = add <vscale x 2 x i64> %a, %mul
+  ret <vscale x 2 x i64> %out
+}
+
+define <vscale x 4 x i32> @svmul_m_ptrue_i32_by_2(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmul_m_ptrue_i32_by_2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add z0.s, z0.s, z0.s
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.nxv4i32(
+      <vscale x 4 x i1> splat(i1 true),
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 2))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmul_m_ptrue_i32_by_5(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmul_m_ptrue_i32_by_5:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #2]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.nxv4i32(
+      <vscale x 4 x i1> splat(i1 true),
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 5))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmul_m_partial_i32_by_5(<vscale x 4 x i1> %pg,
+                                                    <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmul_m_partial_i32_by_5:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov z1.s, #5
+; CHECK-NEXT:    mul z0.s, p0/m, z0.s, z1.s
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.nxv4i32(
+      <vscale x 4 x i1> %pg,
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 5))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmul_u_i32_by_2(<vscale x 4 x i1> %pg,
+                                            <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmul_u_i32_by_2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    add z0.s, z0.s, z0.s
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.u.nxv4i32(
+      <vscale x 4 x i1> %pg,
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 2))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmul_u_i32_by_9_commuted(<vscale x 4 x i1> %pg,
+                                                     <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmul_u_i32_by_9_commuted:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z0.s, lsl #3]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mul.u.nxv4i32(
+      <vscale x 4 x i1> %pg,
+      <vscale x 4 x i32> splat(i32 9),
+      <vscale x 4 x i32> %x)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmla_m_ptrue_i32_by_2(<vscale x 4 x i32> %a,
+                                                  <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmla_m_ptrue_i32_by_2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #1]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mla.nxv4i32(
+      <vscale x 4 x i1> splat(i1 true),
+      <vscale x 4 x i32> %a,
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 2))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmla_m_ptrue_i32_by_8_commuted(
+    <vscale x 4 x i32> %a, <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmla_m_ptrue_i32_by_8_commuted:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #3]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mla.nxv4i32(
+      <vscale x 4 x i1> splat(i1 true),
+      <vscale x 4 x i32> %a,
+      <vscale x 4 x i32> splat(i32 8),
+      <vscale x 4 x i32> %x)
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmla_m_partial_i32_by_4(<vscale x 4 x i1> %pg,
+                                                    <vscale x 4 x i32> %a,
+                                                    <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmla_m_partial_i32_by_4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov z2.s, #4
+; CHECK-NEXT:    mla z0.s, p0/m, z1.s, z2.s
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mla.nxv4i32(
+      <vscale x 4 x i1> %pg,
+      <vscale x 4 x i32> %a,
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 4))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 4 x i32> @svmla_u_i32_by_4(<vscale x 4 x i1> %pg,
+                                            <vscale x 4 x i32> %a,
+                                            <vscale x 4 x i32> %x) {
+; CHECK-LABEL: svmla_u_i32_by_4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.s, [z0.s, z1.s, lsl #2]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 4 x i32> @llvm.aarch64.sve.mla.u.nxv4i32(
+      <vscale x 4 x i1> %pg,
+      <vscale x 4 x i32> %a,
+      <vscale x 4 x i32> %x,
+      <vscale x 4 x i32> splat(i32 4))
+  ret <vscale x 4 x i32> %out
+}
+
+define <vscale x 2 x i64> @svmla_u_i64_by_8(<vscale x 2 x i1> %pg,
+                                            <vscale x 2 x i64> %a,
+                                            <vscale x 2 x i64> %x) {
+; CHECK-LABEL: svmla_u_i64_by_8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    adr z0.d, [z0.d, z1.d, lsl #3]
+; CHECK-NEXT:    ret
+  %out = call <vscale x 2 x i64> @llvm.aarch64.sve.mla.u.nxv2i64(
+      <vscale x 2 x i1> %pg,
+      <vscale x 2 x i64> %a,
+      <vscale x 2 x i64> %x,
+      <vscale x 2 x i64> splat(i64 8))
+  ret <vscale x 2 x i64> %out
+}
+
+declare <vscale x 4 x i32> @llvm.aarch64.sve.mul.nxv4i32(
+    <vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>)
+declare <vscale x 4 x i32> @llvm.aarch64.sve.mul.u.nxv4i32(
+    <vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>)
+declare <vscale x 4 x i32> @llvm.aarch64.sve.mla.nxv4i32(
+    <vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>,
+    <vscale x 4 x i32>)
+declare <vscale x 4 x i32> @llvm.aarch64.sve.mla.u.nxv4i32(
+    <vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>,
+    <vscale x 4 x i32>)
+declare <vscale x 2 x i64> @llvm.aarch64.sve.mla.u.nxv2i64(
+    <vscale x 2 x i1>, <vscale x 2 x i64>, <vscale x 2 x i64>,
+    <vscale x 2 x i64>)
diff --git a/llvm/test/CodeGen/AArch64/sve2-histcnt.ll b/llvm/test/CodeGen/AArch64/sve2-histcnt.ll
index 6596abe2f105a..a49bdafb8a46a 100644
--- a/llvm/test/CodeGen/AArch64/sve2-histcnt.ll
+++ b/llvm/test/CodeGen/AArch64/sve2-histcnt.ll
@@ -147,10 +147,8 @@ define void @histogram_i16_literal_2(ptr %base, <vscale x 4 x i32> %indices, <vs
 ; CHECK-LABEL: histogram_i16_literal_2:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    histcnt z1.s, p0/z, z0.s, z0.s
-; CHECK-NEXT:    mov z3.s, #2 // =0x2
 ; CHECK-NEXT:    ld1h { z2.s }, p0/z, [x0, z0.s, sxtw #1]
-; CHECK-NEXT:    ptrue p1.s
-; CHECK-NEXT:    mad z1.s, p1/m, z3.s, z2.s
+; CHECK-NEXT:    adr z1.s, [z2.s, z1.s, lsl #1]
 ; CHECK-NEXT:    st1h { z1.s }, p0, [x0, z0.s, sxtw #1]
 ; CHECK-NEXT:    ret
   %buckets = getelementptr i16, ptr %base, <vscale x 4 x i32> %indices



More information about the llvm-commits mailing list