[llvm] [ARM] Add MVE support to canCombineStoreAndExtract (PR #194649)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 07:58:23 PDT 2026
https://github.com/LumioseSil created https://github.com/llvm/llvm-project/pull/194649
MVE can do a store + vector extract on any vector that fits perfectly in a Q register.
>From c846e2d9c06be6d93010d7964fa2d39240f64292 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Tue, 28 Apr 2026 10:55:03 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)
---
llvm/test/CodeGen/ARM/vector-promotion.ll | 47 +++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/llvm/test/CodeGen/ARM/vector-promotion.ll b/llvm/test/CodeGen/ARM/vector-promotion.ll
index 344014ad80449..4e3fdd0d353ba 100644
--- a/llvm/test/CodeGen/ARM/vector-promotion.ll
+++ b/llvm/test/CodeGen/ARM/vector-promotion.ll
@@ -1,6 +1,9 @@
; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-NORMAL %s
; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S -stress-cgp-store-extract | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-STRESS %s
; RUN: llc -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon | FileCheck --check-prefix=ASM %s
+; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv8.1m.main-none-eabi %s -o - -mattr=+mve -S | FileCheck --check-prefix=IR-MVE %s
+; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv8.1m.main-none-eabi %s -o - -mattr=+mve -S -stress-cgp-store-extract | FileCheck --check-prefix=IR-MVE-STRESS %s
+; RUN: llc -mtriple=thumbv8.1m.main-none-eabi %s -o - -mattr=+mve | FileCheck --check-prefix=ASM-MVE %s
; IR-BOTH-LABEL: @simpleOneInstructionPromotion
; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1
@@ -393,3 +396,47 @@ define void @simpleOneInstructionPromotion4x32(ptr %addr1, ptr %dest) {
store i32 %out, ptr %dest, align 1
ret void
}
+
+; MVE only supports the Q-register (128-bit) case for this combine.
+; IR-MVE-LABEL: @simpleOneInstructionPromotionMVE4x32
+; IR-MVE: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, ptr %addr1
+; IR-MVE-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[LOAD]], i32 1
+; IR-MVE-NEXT: [[OUT:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
+; IR-MVE-NEXT: store i32 [[OUT]], ptr %dest
+; IR-MVE-NEXT: ret
+; IR-MVE-STRESS-LABEL: @simpleOneInstructionPromotionMVE4x32
+; IR-MVE-STRESS: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, ptr %addr1
+; IR-MVE-STRESS-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <4 x i32> [[LOAD]], <i32 poison, i32 1, i32 poison, i32 poison>
+; IR-MVE-STRESS-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[VECTOR_OR]], i32 1
+; IR-MVE-STRESS-NEXT: store i32 [[EXTRACT]], ptr %dest
+; IR-MVE-STRESS-NEXT: ret
+; ASM-MVE-LABEL: simpleOneInstructionPromotionMVE4x32:
+define void @simpleOneInstructionPromotionMVE4x32(ptr %addr1, ptr %dest) {
+ %in1 = load <4 x i32>, ptr %addr1, align 16
+ %extract = extractelement <4 x i32> %in1, i32 1
+ %out = or i32 %extract, 1
+ store i32 %out, ptr %dest, align 4
+ ret void
+}
+
+; For MVE-only targets, 64-bit vectors should not use this combine.
+; IR-MVE-LABEL: @simpleOneInstructionPromotionMVE2x32
+; IR-MVE: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1
+; IR-MVE-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1
+; IR-MVE-NEXT: [[OUT:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
+; IR-MVE-NEXT: store i32 [[OUT]], ptr %dest
+; IR-MVE-NEXT: ret
+; IR-MVE-STRESS-LABEL: @simpleOneInstructionPromotionMVE2x32
+; IR-MVE-STRESS: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1
+; IR-MVE-STRESS-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 poison, i32 1>
+; IR-MVE-STRESS-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR]], i32 1
+; IR-MVE-STRESS-NEXT: store i32 [[EXTRACT]], ptr %dest
+; IR-MVE-STRESS-NEXT: ret
+; ASM-MVE-LABEL: simpleOneInstructionPromotionMVE2x32:
+define void @simpleOneInstructionPromotionMVE2x32(ptr %addr1, ptr %dest) {
+ %in1 = load <2 x i32>, ptr %addr1, align 8
+ %extract = extractelement <2 x i32> %in1, i32 1
+ %out = or i32 %extract, 1
+ store i32 %out, ptr %dest, align 4
+ ret void
+}
>From f58964fab80d4d0efe9c7389ae2dff19bc17bba2 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Tue, 28 Apr 2026 10:57:54 -0400
Subject: [PATCH 2/2] [ARM] Add MVE support to canCombineStoreAndExtract
MVE can do a store + vector extract on any vector that fits perfectly in a Q register.
---
llvm/lib/Target/ARM/ARMISelLowering.cpp | 11 ++++++++---
llvm/test/CodeGen/ARM/vector-promotion.ll | 6 +++---
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 17d57c1a24407..75fa5cefbf6b3 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -21436,8 +21436,8 @@ void ARMTargetLowering::insertSSPDeclarations(
bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
unsigned &Cost) const {
- // If we do not have NEON, vector types are not natively supported.
- if (!Subtarget->hasNEON())
+ // If we do not have NEON or MVE, vector types are not natively supported.
+ if (!Subtarget->hasNEON() && !Subtarget->hasMVEIntegerOps())
return false;
// Floating point values and vector values map to the same register file.
@@ -21456,7 +21456,12 @@ bool ARMTargetLowering::canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
unsigned BitWidth = VectorTy->getPrimitiveSizeInBits().getFixedValue();
// We can do a store + vector extract on any vector that fits perfectly in a D
// or Q register.
- if (BitWidth == 64 || BitWidth == 128) {
+ if (Subtarget->hasNEON() && (BitWidth == 64 || BitWidth == 128)) {
+ Cost = 0;
+ return true;
+ }
+
+ if (Subtarget->hasMVEIntegerOps() && BitWidth == 128) {
Cost = 0;
return true;
}
diff --git a/llvm/test/CodeGen/ARM/vector-promotion.ll b/llvm/test/CodeGen/ARM/vector-promotion.ll
index 4e3fdd0d353ba..59916a5a6fcdc 100644
--- a/llvm/test/CodeGen/ARM/vector-promotion.ll
+++ b/llvm/test/CodeGen/ARM/vector-promotion.ll
@@ -400,9 +400,9 @@ define void @simpleOneInstructionPromotion4x32(ptr %addr1, ptr %dest) {
; MVE only supports the Q-register (128-bit) case for this combine.
; IR-MVE-LABEL: @simpleOneInstructionPromotionMVE4x32
; IR-MVE: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, ptr %addr1
-; IR-MVE-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[LOAD]], i32 1
-; IR-MVE-NEXT: [[OUT:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1
-; IR-MVE-NEXT: store i32 [[OUT]], ptr %dest
+; IR-MVE-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <4 x i32> [[LOAD]], <i32 poison, i32 1, i32 poison, i32 poison>
+; IR-MVE-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[VECTOR_OR]], i32 1
+; IR-MVE-NEXT: store i32 [[EXTRACT]], ptr %dest
; IR-MVE-NEXT: ret
; IR-MVE-STRESS-LABEL: @simpleOneInstructionPromotionMVE4x32
; IR-MVE-STRESS: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, ptr %addr1
More information about the llvm-commits
mailing list