[ARM][MVE] Add SLI and SRI recognition. - #183471
Merged
Merged
Conversation
This uses the newly added code from llvm#182051 to optimize to MVE sli and sri. The only major difference is the legal types supported.
Member
|
@llvm/pr-subscribers-backend-arm Author: David Green (davemgreen) ChangesThis uses the newly added code from #182051 to optimize to MVE sli and sri. The only major difference is the legal types supported, but we also lower intrinsics via VSLIIMM/VSLIIMM, so that only one tablegen pattern is needed. Full diff: https://github.com/llvm/llvm-project/pull/183471.diff 3 Files Affected:
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index bd851ccf13501..ef34cb1119168 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -3958,6 +3958,12 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
case Intrinsic::arm_mve_asrl:
return DAG.getNode(ARMISD::ASRL, SDLoc(Op), Op->getVTList(),
Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
+ case Intrinsic::arm_mve_vsli:
+ return DAG.getNode(ARMISD::VSLIIMM, SDLoc(Op), Op->getVTList(),
+ Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
+ case Intrinsic::arm_mve_vsri:
+ return DAG.getNode(ARMISD::VSRIIMM, SDLoc(Op), Op->getVTList(),
+ Op.getOperand(1), Op.getOperand(2), Op.getOperand(3));
}
}
@@ -14692,8 +14698,10 @@ static SDValue PerformORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
// (or (and X, C1), (srl Y, C2)) -> VSRI X, Y, #C2
// (or (and X, C1), (shl Y, C2)) -> VSLI X, Y, #C2
- if (Subtarget->hasNEON() && VT.isVector() &&
- DAG.getTargetLoweringInfo().isTypeLegal(VT)) {
+ if (VT.isVector() &&
+ ((Subtarget->hasNEON() && DAG.getTargetLoweringInfo().isTypeLegal(VT)) ||
+ (Subtarget->hasMVEIntegerOps() &&
+ (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32)))) {
if (SDValue ShiftInsert =
PerformORCombineToShiftInsert(DAG, N0, N1, VT, dl))
return ShiftInsert;
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index d4b39676b7b4f..38f36cb239535 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -3280,27 +3280,27 @@ def MVE_VSLIimm32 : MVE_VSxI_imm<"vsli", "32", 0b1,imm0_31, 0b10> {
let Inst{21} = 0b1;
}
-multiclass MVE_VSxI_patterns<MVE_VSxI_imm inst, string name,
- MVEVectorVTInfo VTI> {
+multiclass MVE_VSxI_patterns<MVE_VSxI_imm inst, SDPatternOperator Node,
+ SDPatternOperator PredIntr, MVEVectorVTInfo VTI> {
defvar inparams = (? (VTI.Vec MQPR:$QdSrc), (VTI.Vec MQPR:$Qm),
(inst.immediateType:$imm));
defvar outparams = (inst (VTI.Vec MQPR:$QdSrc), (VTI.Vec MQPR:$Qm),
(inst.immediateType:$imm));
- defvar unpred_int = !cast<Intrinsic>("int_arm_mve_" # name);
- defvar pred_int = !cast<Intrinsic>("int_arm_mve_" # name # "_predicated");
- def : Pat<(VTI.Vec !setdagop(inparams, unpred_int)),
+ def : Pat<(VTI.Vec !setdagop(inparams, Node)),
(VTI.Vec outparams)>;
- def : Pat<(VTI.Vec !con(inparams, (pred_int (VTI.Pred VCCR:$pred)))),
+ def : Pat<(VTI.Vec !con(inparams, (PredIntr (VTI.Pred VCCR:$pred)))),
(VTI.Vec !con(outparams, (? ARMVCCThen, VCCR:$pred, zero_reg)))>;
}
-defm : MVE_VSxI_patterns<MVE_VSLIimm8, "vsli", MVE_v16i8>;
-defm : MVE_VSxI_patterns<MVE_VSLIimm16, "vsli", MVE_v8i16>;
-defm : MVE_VSxI_patterns<MVE_VSLIimm32, "vsli", MVE_v4i32>;
-defm : MVE_VSxI_patterns<MVE_VSRIimm8, "vsri", MVE_v16i8>;
-defm : MVE_VSxI_patterns<MVE_VSRIimm16, "vsri", MVE_v8i16>;
-defm : MVE_VSxI_patterns<MVE_VSRIimm32, "vsri", MVE_v4i32>;
+let Predicates = [HasMVEInt] in {
+defm : MVE_VSxI_patterns<MVE_VSLIimm8, NEONvsliImm, int_arm_mve_vsli_predicated, MVE_v16i8>;
+defm : MVE_VSxI_patterns<MVE_VSLIimm16, NEONvsliImm, int_arm_mve_vsli_predicated, MVE_v8i16>;
+defm : MVE_VSxI_patterns<MVE_VSLIimm32, NEONvsliImm, int_arm_mve_vsli_predicated, MVE_v4i32>;
+defm : MVE_VSxI_patterns<MVE_VSRIimm8, NEONvsriImm, int_arm_mve_vsri_predicated, MVE_v16i8>;
+defm : MVE_VSxI_patterns<MVE_VSRIimm16, NEONvsriImm, int_arm_mve_vsri_predicated, MVE_v8i16>;
+defm : MVE_VSxI_patterns<MVE_VSRIimm32, NEONvsriImm, int_arm_mve_vsri_predicated, MVE_v4i32>;
+}
class MVE_VQSHL_imm<MVEVectorVTInfo VTI_, Operand immType>
: MVE_shift_with_imm<"vqshl", VTI_.Suffix, (outs MQPR:$Qd),
diff --git a/llvm/test/CodeGen/Thumb2/mve-sli-sri.ll b/llvm/test/CodeGen/Thumb2/mve-sli-sri.ll
index 2fc8761762b94..f768580044f93 100644
--- a/llvm/test/CodeGen/Thumb2/mve-sli-sri.ll
+++ b/llvm/test/CodeGen/Thumb2/mve-sli-sri.ll
@@ -4,10 +4,7 @@
define <8 x i8> @testLeftGood8x8(<8 x i8> %src1, <8 x i8> %src2) {
; CHECK-LABEL: testLeftGood8x8:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmov.i16 q2, #0x7
-; CHECK-NEXT: vshl.i16 q1, q1, #3
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsli.16 q0, q1, #3
; CHECK-NEXT: bx lr
%and.i = and <8 x i8> %src1, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
%vshl_n = shl <8 x i8> %src2, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>
@@ -62,10 +59,7 @@ define <8 x i8> @testRightBad8x8(<8 x i8> %src1, <8 x i8> %src2) {
define <16 x i8> @testLeftGood16x8(<16 x i8> %src1, <16 x i8> %src2) {
; CHECK-LABEL: testLeftGood16x8:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmov.i8 q2, #0x7
-; CHECK-NEXT: vshl.i8 q1, q1, #3
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsli.8 q0, q1, #3
; CHECK-NEXT: bx lr
%and.i = and <16 x i8> %src1, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
%vshl_n = shl <16 x i8> %src2, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>
@@ -90,10 +84,7 @@ define <16 x i8> @testLeftBad16x8(<16 x i8> %src1, <16 x i8> %src2) {
define <16 x i8> @testRightGood16x8(<16 x i8> %src1, <16 x i8> %src2) {
; CHECK-LABEL: testRightGood16x8:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmov.i8 q2, #0xe0
-; CHECK-NEXT: vshr.u8 q1, q1, #3
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsri.8 q0, q1, #3
; CHECK-NEXT: bx lr
%and.i = and <16 x i8> %src1, <i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224, i8 224>
%vshl_n = lshr <16 x i8> %src2, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>
@@ -118,10 +109,7 @@ define <16 x i8> @testRightBad16x8(<16 x i8> %src1, <16 x i8> %src2) {
define <4 x i16> @testLeftGood4x16(<4 x i16> %src1, <4 x i16> %src2) {
; CHECK-LABEL: testLeftGood4x16:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmov.i32 q2, #0x3fff
-; CHECK-NEXT: vshl.i32 q1, q1, #14
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsli.32 q0, q1, #14
; CHECK-NEXT: bx lr
%and.i = and <4 x i16> %src1, <i16 16383, i16 16383, i16 16383, i16 16383>
%vshl_n = shl <4 x i16> %src2, <i16 14, i16 14, i16 14, i16 14>
@@ -347,10 +335,7 @@ define <2 x i32> @testRightBad2x32(<2 x i32> %src1, <2 x i32> %src2) {
define <4 x i32> @testLeftGood4x32(<4 x i32> %src1, <4 x i32> %src2) {
; CHECK-LABEL: testLeftGood4x32:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmov.i32 q2, #0x3fffff
-; CHECK-NEXT: vshl.i32 q1, q1, #22
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsli.32 q0, q1, #22
; CHECK-NEXT: bx lr
%and.i = and <4 x i32> %src1, <i32 4194303, i32 4194303, i32 4194303, i32 4194303>
%vshl_n = shl <4 x i32> %src2, <i32 22, i32 22, i32 22, i32 22>
@@ -377,10 +362,7 @@ define <4 x i32> @testLeftBad4x32(<4 x i32> %src1, <4 x i32> %src2) {
define <4 x i32> @testRightGood4x32(<4 x i32> %src1, <4 x i32> %src2) {
; CHECK-LABEL: testRightGood4x32:
; CHECK: @ %bb.0:
-; CHECK-NEXT: vmvn.i32 q2, #0x3ff
-; CHECK-NEXT: vshr.u32 q1, q1, #22
-; CHECK-NEXT: vand q0, q0, q2
-; CHECK-NEXT: vorr q0, q0, q1
+; CHECK-NEXT: vsri.32 q0, q1, #22
; CHECK-NEXT: bx lr
%and.i = and <4 x i32> %src1, <i32 4294966272, i32 4294966272, i32 4294966272, i32 4294966272>
%vshl_n = lshr <4 x i32> %src2, <i32 22, i32 22, i32 22, i32 22>
|
sahas3
pushed a commit
to sahas3/llvm-project
that referenced
this pull request
Mar 4, 2026
This uses the newly added code from llvm#182051 to optimize to MVE sli and sri. The only major difference is the legal types supported, but we also lower intrinsics via VSLIIMM/VSLIIMM, so that only one tablegen pattern is needed.
sujianIBM
pushed a commit
to sujianIBM/llvm-project
that referenced
this pull request
Mar 5, 2026
This uses the newly added code from llvm#182051 to optimize to MVE sli and sri. The only major difference is the legal types supported, but we also lower intrinsics via VSLIIMM/VSLIIMM, so that only one tablegen pattern is needed.
This was referenced Apr 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This uses the newly added code from #182051 to optimize to MVE sli and sri. The only major difference is the legal types supported, but we also lower intrinsics via VSLIIMM/VSLIIMM, so that only one tablegen pattern is needed.