[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
Wed Jun 10 02:09:50 PDT 2026
================
@@ -0,0 +1,182 @@
+; Check that all-active SVE multiplies by small constants select ADD/ADR
+; sequences instead of MUL/MLA.
+; 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: add z0.s, z0.s, z0.s
+; 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 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 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
+ %pg = call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
+ %dup = call <vscale x 4 x i32> @llvm.aarch64.sve.dup.x.nxv4i32(i32 2)
+ %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> %dup)
----------------
tommat01 wrote:
Done
https://github.com/llvm/llvm-project/pull/198566
More information about the llvm-commits
mailing list