[llvm] [MIPS] [MSA] Widen v2i8, v216 and v2i32 vectors (PR #123040)
Cinhi Young via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 20 22:05:59 PST 2025
https://github.com/Cyanoxygen updated https://github.com/llvm/llvm-project/pull/123040
>From 407183f49600b3e19a2e3079fe26007a1125e5e9 Mon Sep 17 00:00:00 2001
From: Xinhui Yang <cyan at cyano.uk>
Date: Tue, 14 Jan 2025 23:56:32 +0800
Subject: [PATCH 1/2] [MIPS][MSA] Widen v2 vectors to the register length for
MSA
Currently v2i8, v2i16 and v2i32 are being promoted to v2i64 which casts
the vector back and forth, and instructions with the wrong format are
being used. Widening them to avoid unnecessary bitcasts, loads and
stores, and ensure the correct element size is used.
* tests/CodeGen/Mips: Update tests after widening of v2 vectors.
---
llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 39 +++
llvm/lib/Target/Mips/MipsSEISelLowering.h | 3 +
llvm/test/CodeGen/Mips/cconv/vector.ll | 320 ++++++++++----------
3 files changed, 208 insertions(+), 154 deletions(-)
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 818b1683bb867e..3519781fc9e0d7 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -59,6 +59,45 @@ static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
"stores to their single precision "
"counterparts"));
+// Widen the v2 vectors to the register width, i.e. v2i16 -> v8i16,
+// v2i32 -> v4i32, etc, to ensure the correct rail size is used, i.e.
+// INST.h for v16, INST.w for v32, INST.d for v64.
+TargetLoweringBase::LegalizeTypeAction
+MipsSETargetLowering::getPreferredVectorAction(MVT VT) const {
+ if (this->Subtarget.hasMSA()) {
+ switch (VT.SimpleTy) {
+ // Leave v2i1 vectors to be promoted to larger ones.
+ // Other i1 types will be promoted by default.
+ case MVT::v2i1:
+ return TypePromoteInteger;
+ break;
+ // 16-bit vector types (v2 and longer)
+ case MVT::v2i8:
+ // 32-bit vector types (v2 and longer)
+ case MVT::v2i16:
+ case MVT::v4i8:
+ // 64-bit vector types (v2 and longer)
+ case MVT::v2i32:
+ case MVT::v4i16:
+ case MVT::v8i8:
+ return TypeWidenVector;
+ break;
+ // Only word (.w) and doubleword (.d) are available for floating point
+ // vectors. That means floating point vectors should be either v2f64
+ // or v4f32.
+ // Here we only explicitly widen the f32 types - f16 will be promoted
+ // by default.
+ case MVT::v2f32:
+ case MVT::v3f32:
+ return TypeWidenVector;
+ // v2i64 is already 128-bit wide.
+ default:
+ break;
+ }
+ }
+ return TargetLoweringBase::getPreferredVectorAction(VT);
+}
+
MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
const MipsSubtarget &STI)
: MipsTargetLowering(TM, STI) {
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h
index 43b88a9f095226..675131aefb6dd9 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h
@@ -45,6 +45,9 @@ class TargetRegisterClass;
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
unsigned *Fast = nullptr) const override;
+ TargetLoweringBase::LegalizeTypeAction
+ getPreferredVectorAction(MVT VT) const override;
+
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
diff --git a/llvm/test/CodeGen/Mips/cconv/vector.ll b/llvm/test/CodeGen/Mips/cconv/vector.ll
index 28a7dc046139b2..82139dd352a4c4 100644
--- a/llvm/test/CodeGen/Mips/cconv/vector.ll
+++ b/llvm/test/CodeGen/Mips/cconv/vector.ll
@@ -84,30 +84,6 @@ define <2 x i8> @i8_2(<2 x i8> %a, <2 x i8> %b) {
; MIPS32R5EB-NEXT: jr $ra
; MIPS32R5EB-NEXT: nop
;
-; MIPS64R5-LABEL: i8_2:
-; MIPS64R5: # %bb.0:
-; MIPS64R5-NEXT: daddiu $sp, $sp, -16
-; MIPS64R5-NEXT: .cfi_def_cfa_offset 16
-; MIPS64R5-NEXT: sh $5, 8($sp)
-; MIPS64R5-NEXT: sh $4, 12($sp)
-; MIPS64R5-NEXT: lb $1, 9($sp)
-; MIPS64R5-NEXT: lb $2, 8($sp)
-; MIPS64R5-NEXT: insert.d $w0[0], $2
-; MIPS64R5-NEXT: insert.d $w0[1], $1
-; MIPS64R5-NEXT: lb $1, 13($sp)
-; MIPS64R5-NEXT: lb $2, 12($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w1, $w0
-; MIPS64R5-NEXT: copy_s.d $1, $w0[0]
-; MIPS64R5-NEXT: copy_s.d $2, $w0[1]
-; MIPS64R5-NEXT: sb $2, 5($sp)
-; MIPS64R5-NEXT: sb $1, 4($sp)
-; MIPS64R5-NEXT: lh $2, 4($sp)
-; MIPS64R5-NEXT: daddiu $sp, $sp, 16
-; MIPS64R5-NEXT: jr $ra
-; MIPS64R5-NEXT: nop
-;
; MIPS32R5EL-LABEL: i8_2:
; MIPS32R5EL: # %bb.0:
; MIPS32R5EL-NEXT: addiu $sp, $sp, -64
@@ -144,6 +120,38 @@ define <2 x i8> @i8_2(<2 x i8> %a, <2 x i8> %b) {
; MIPS32R5EL-NEXT: addiu $sp, $sp, 64
; MIPS32R5EL-NEXT: jr $ra
; MIPS32R5EL-NEXT: nop
+;
+; MIPS64R5EB-LABEL: i8_2:
+; MIPS64R5EB: # %bb.0:
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, -48
+; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 48
+; MIPS64R5EB-NEXT: sh $5, 16($sp)
+; MIPS64R5EB-NEXT: sh $4, 0($sp)
+; MIPS64R5EB-NEXT: ld.b $w0, 16($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 0($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w1, $w0
+; MIPS64R5EB-NEXT: shf.b $w0, $w0, 177
+; MIPS64R5EB-NEXT: copy_s.h $1, $w0[0]
+; MIPS64R5EB-NEXT: sh $1, 44($sp)
+; MIPS64R5EB-NEXT: lh $2, 44($sp)
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, 48
+; MIPS64R5EB-NEXT: jr $ra
+;
+; MIPS64R5EL-LABEL: i8_2:
+; MIPS64R5EL: # %bb.0:
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, -48
+; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 48
+; MIPS64R5EL-NEXT: sh $5, 16($sp)
+; MIPS64R5EL-NEXT: sh $4, 0($sp)
+; MIPS64R5EL-NEXT: ld.b $w0, 16($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 0($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w1, $w0
+; MIPS64R5EL-NEXT: copy_s.h $1, $w0[0]
+; MIPS64R5EL-NEXT: sh $1, 44($sp)
+; MIPS64R5EL-NEXT: lh $2, 44($sp)
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, 48
+; MIPS64R5EL-NEXT: jr $ra
+; MIPS64R5EL-NEXT: nop
%1 = add <2 x i8> %a, %b
ret <2 x i8> %1
}
@@ -297,59 +305,68 @@ define <2 x i8> @i8x2_7(<2 x i8> %a, <2 x i8> %b, <2 x i8> %c, <2 x i8> %d, <2 x
; MIPS32R5EB-NEXT: jr $ra
; MIPS32R5EB-NEXT: nop
;
-; MIPS64R5-LABEL: i8x2_7:
-; MIPS64R5: # %bb.0: # %entry
-; MIPS64R5-NEXT: daddiu $sp, $sp, -32
-; MIPS64R5-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5-NEXT: sh $5, 24($sp)
-; MIPS64R5-NEXT: sh $4, 28($sp)
-; MIPS64R5-NEXT: lb $1, 25($sp)
-; MIPS64R5-NEXT: lb $2, 24($sp)
-; MIPS64R5-NEXT: insert.d $w0[0], $2
-; MIPS64R5-NEXT: insert.d $w0[1], $1
-; MIPS64R5-NEXT: lb $1, 29($sp)
-; MIPS64R5-NEXT: lb $2, 28($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w1, $w0
-; MIPS64R5-NEXT: sh $6, 20($sp)
-; MIPS64R5-NEXT: lb $1, 21($sp)
-; MIPS64R5-NEXT: lb $2, 20($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w0, $w1
-; MIPS64R5-NEXT: sh $7, 16($sp)
-; MIPS64R5-NEXT: lb $1, 17($sp)
-; MIPS64R5-NEXT: lb $2, 16($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w0, $w1
-; MIPS64R5-NEXT: sh $8, 12($sp)
-; MIPS64R5-NEXT: lb $1, 13($sp)
-; MIPS64R5-NEXT: lb $2, 12($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w0, $w1
-; MIPS64R5-NEXT: sh $9, 8($sp)
-; MIPS64R5-NEXT: lb $1, 9($sp)
-; MIPS64R5-NEXT: lb $2, 8($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w0, $w1
-; MIPS64R5-NEXT: sh $10, 4($sp)
-; MIPS64R5-NEXT: lb $1, 5($sp)
-; MIPS64R5-NEXT: lb $2, 4($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w0, $w1
-; MIPS64R5-NEXT: copy_s.d $1, $w0[0]
-; MIPS64R5-NEXT: copy_s.d $2, $w0[1]
-; MIPS64R5-NEXT: sb $2, 1($sp)
-; MIPS64R5-NEXT: sb $1, 0($sp)
-; MIPS64R5-NEXT: lh $2, 0($sp)
-; MIPS64R5-NEXT: daddiu $sp, $sp, 32
-; MIPS64R5-NEXT: jr $ra
-; MIPS64R5-NEXT: nop
+; MIPS64R5EB-LABEL: i8x2_7:
+; MIPS64R5EB: # %bb.0: # %entry
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, -128
+; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 128
+; MIPS64R5EB-NEXT: sh $5, 16($sp)
+; MIPS64R5EB-NEXT: sh $4, 0($sp)
+; MIPS64R5EB-NEXT: ld.b $w0, 16($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 0($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w1, $w0
+; MIPS64R5EB-NEXT: sh $6, 32($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 32($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EB-NEXT: sh $7, 48($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 48($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EB-NEXT: sh $8, 64($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 64($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EB-NEXT: sh $9, 80($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 80($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EB-NEXT: sh $10, 96($sp)
+; MIPS64R5EB-NEXT: ld.b $w1, 96($sp)
+; MIPS64R5EB-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EB-NEXT: shf.b $w0, $w0, 177
+; MIPS64R5EB-NEXT: copy_s.h $1, $w0[0]
+; MIPS64R5EB-NEXT: sh $1, 124($sp)
+; MIPS64R5EB-NEXT: lh $2, 124($sp)
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, 128
+; MIPS64R5EB-NEXT: jr $ra
+; MIPS64R5EB-NEXT: nop
+;
+; MIPS64R5EL-LABEL: i8x2_7:
+; MIPS64R5EL: # %bb.0: # %entry
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, -128
+; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 128
+; MIPS64R5EL-NEXT: sh $5, 16($sp)
+; MIPS64R5EL-NEXT: sh $4, 0($sp)
+; MIPS64R5EL-NEXT: ld.b $w0, 16($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 0($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w1, $w0
+; MIPS64R5EL-NEXT: sh $6, 32($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 32($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EL-NEXT: sh $7, 48($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 48($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EL-NEXT: sh $8, 64($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 64($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EL-NEXT: sh $9, 80($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 80($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EL-NEXT: sh $10, 96($sp)
+; MIPS64R5EL-NEXT: ld.b $w1, 96($sp)
+; MIPS64R5EL-NEXT: addv.b $w0, $w0, $w1
+; MIPS64R5EL-NEXT: copy_s.h $1, $w0[0]
+; MIPS64R5EL-NEXT: sh $1, 124($sp)
+; MIPS64R5EL-NEXT: lh $2, 124($sp)
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, 128
+; MIPS64R5EL-NEXT: jr $ra
+; MIPS64R5EL-NEXT: nop
;
; MIPS32EL-LABEL: i8x2_7:
; MIPS32EL: # %bb.0: # %entry
@@ -1257,30 +1274,6 @@ define <2 x i16> @i16_2(<2 x i16> %a, <2 x i16> %b) {
; MIPS32R5EB-NEXT: jr $ra
; MIPS32R5EB-NEXT: nop
;
-; MIPS64R5-LABEL: i16_2:
-; MIPS64R5: # %bb.0:
-; MIPS64R5-NEXT: daddiu $sp, $sp, -16
-; MIPS64R5-NEXT: .cfi_def_cfa_offset 16
-; MIPS64R5-NEXT: sw $5, 8($sp)
-; MIPS64R5-NEXT: sw $4, 12($sp)
-; MIPS64R5-NEXT: lh $1, 10($sp)
-; MIPS64R5-NEXT: lh $2, 8($sp)
-; MIPS64R5-NEXT: insert.d $w0[0], $2
-; MIPS64R5-NEXT: insert.d $w0[1], $1
-; MIPS64R5-NEXT: lh $1, 14($sp)
-; MIPS64R5-NEXT: lh $2, 12($sp)
-; MIPS64R5-NEXT: insert.d $w1[0], $2
-; MIPS64R5-NEXT: insert.d $w1[1], $1
-; MIPS64R5-NEXT: addv.d $w0, $w1, $w0
-; MIPS64R5-NEXT: copy_s.d $1, $w0[0]
-; MIPS64R5-NEXT: copy_s.d $2, $w0[1]
-; MIPS64R5-NEXT: sh $2, 6($sp)
-; MIPS64R5-NEXT: sh $1, 4($sp)
-; MIPS64R5-NEXT: lw $2, 4($sp)
-; MIPS64R5-NEXT: daddiu $sp, $sp, 16
-; MIPS64R5-NEXT: jr $ra
-; MIPS64R5-NEXT: nop
-;
; MIPS32R5EL-LABEL: i16_2:
; MIPS32R5EL: # %bb.0:
; MIPS32R5EL-NEXT: addiu $sp, $sp, -64
@@ -1317,6 +1310,38 @@ define <2 x i16> @i16_2(<2 x i16> %a, <2 x i16> %b) {
; MIPS32R5EL-NEXT: addiu $sp, $sp, 64
; MIPS32R5EL-NEXT: jr $ra
; MIPS32R5EL-NEXT: nop
+;
+; MIPS64R5EB-LABEL: i16_2:
+; MIPS64R5EB: # %bb.0:
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, -32
+; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 32
+; MIPS64R5EB-NEXT: sll $1, $5, 0
+; MIPS64R5EB-NEXT: sw $1, 16($sp)
+; MIPS64R5EB-NEXT: sll $1, $4, 0
+; MIPS64R5EB-NEXT: sw $1, 0($sp)
+; MIPS64R5EB-NEXT: ld.h $w0, 16($sp)
+; MIPS64R5EB-NEXT: ld.h $w1, 0($sp)
+; MIPS64R5EB-NEXT: addv.h $w0, $w1, $w0
+; MIPS64R5EB-NEXT: shf.h $w0, $w0, 177
+; MIPS64R5EB-NEXT: copy_s.w $2, $w0[0]
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EB-NEXT: jr $ra
+; MIPS64R5EB-NEXT: nop
+;
+; MIPS64R5EL-LABEL: i16_2:
+; MIPS64R5EL: # %bb.0:
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, -32
+; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 32
+; MIPS64R5EL-NEXT: sll $1, $5, 0
+; MIPS64R5EL-NEXT: sw $1, 16($sp)
+; MIPS64R5EL-NEXT: sll $1, $4, 0
+; MIPS64R5EL-NEXT: sw $1, 0($sp)
+; MIPS64R5EL-NEXT: ld.h $w0, 16($sp)
+; MIPS64R5EL-NEXT: ld.h $w1, 0($sp)
+; MIPS64R5EL-NEXT: addv.h $w0, $w1, $w0
+; MIPS64R5EL-NEXT: copy_s.w $2, $w0[0]
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EL-NEXT: jr $ra
%1 = add <2 x i16> %a, %b
ret <2 x i16> %1
}
@@ -1751,18 +1776,13 @@ define <2 x i32> @i32_2(<2 x i32> %a, <2 x i32> %b) {
; MIPS64R5EB: # %bb.0:
; MIPS64R5EB-NEXT: daddiu $sp, $sp, -32
; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5EB-NEXT: dsrl $1, $5, 32
-; MIPS64R5EB-NEXT: insert.d $w0[0], $1
-; MIPS64R5EB-NEXT: insert.d $w0[1], $5
-; MIPS64R5EB-NEXT: dsrl $1, $4, 32
-; MIPS64R5EB-NEXT: insert.d $w1[0], $1
-; MIPS64R5EB-NEXT: insert.d $w1[1], $4
-; MIPS64R5EB-NEXT: addv.d $w0, $w1, $w0
-; MIPS64R5EB-NEXT: copy_s.d $1, $w0[0]
-; MIPS64R5EB-NEXT: copy_s.d $2, $w0[1]
-; MIPS64R5EB-NEXT: sw $2, 12($sp)
-; MIPS64R5EB-NEXT: sw $1, 8($sp)
-; MIPS64R5EB-NEXT: ld $2, 8($sp)
+; MIPS64R5EB-NEXT: sd $5, 16($sp)
+; MIPS64R5EB-NEXT: sd $4, 0($sp)
+; MIPS64R5EB-NEXT: ld.w $w0, 16($sp)
+; MIPS64R5EB-NEXT: ld.w $w1, 0($sp)
+; MIPS64R5EB-NEXT: addv.w $w0, $w1, $w0
+; MIPS64R5EB-NEXT: shf.w $w0, $w0, 177
+; MIPS64R5EB-NEXT: copy_s.d $2, $w0[0]
; MIPS64R5EB-NEXT: daddiu $sp, $sp, 32
; MIPS64R5EB-NEXT: jr $ra
; MIPS64R5EB-NEXT: nop
@@ -1800,19 +1820,11 @@ define <2 x i32> @i32_2(<2 x i32> %a, <2 x i32> %b) {
; MIPS64R5EL-NEXT: daddiu $sp, $sp, -32
; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 32
; MIPS64R5EL-NEXT: sd $5, 16($sp)
-; MIPS64R5EL-NEXT: sd $4, 24($sp)
-; MIPS64R5EL-NEXT: lw $1, 20($sp)
-; MIPS64R5EL-NEXT: insert.d $w0[0], $5
-; MIPS64R5EL-NEXT: insert.d $w0[1], $1
-; MIPS64R5EL-NEXT: lw $1, 28($sp)
-; MIPS64R5EL-NEXT: insert.d $w1[0], $4
-; MIPS64R5EL-NEXT: insert.d $w1[1], $1
-; MIPS64R5EL-NEXT: addv.d $w0, $w1, $w0
-; MIPS64R5EL-NEXT: copy_s.d $1, $w0[0]
-; MIPS64R5EL-NEXT: copy_s.d $2, $w0[1]
-; MIPS64R5EL-NEXT: sw $2, 12($sp)
-; MIPS64R5EL-NEXT: sw $1, 8($sp)
-; MIPS64R5EL-NEXT: ld $2, 8($sp)
+; MIPS64R5EL-NEXT: sd $4, 0($sp)
+; MIPS64R5EL-NEXT: ld.w $w0, 16($sp)
+; MIPS64R5EL-NEXT: ld.w $w1, 0($sp)
+; MIPS64R5EL-NEXT: addv.w $w0, $w1, $w0
+; MIPS64R5EL-NEXT: copy_s.d $2, $w0[0]
; MIPS64R5EL-NEXT: daddiu $sp, $sp, 32
; MIPS64R5EL-NEXT: jr $ra
; MIPS64R5EL-NEXT: nop
@@ -4078,10 +4090,10 @@ define void @calli16_2() {
;
; MIPS64R5EB-LABEL: calli16_2:
; MIPS64R5EB: # %bb.0: # %entry
-; MIPS64R5EB-NEXT: daddiu $sp, $sp, -32
-; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5EB-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill
-; MIPS64R5EB-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, -16
+; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 16
+; MIPS64R5EB-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPS64R5EB-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill
; MIPS64R5EB-NEXT: .cfi_offset 31, -8
; MIPS64R5EB-NEXT: .cfi_offset 28, -16
; MIPS64R5EB-NEXT: lui $1, %hi(%neg(%gp_rel(calli16_2)))
@@ -4096,9 +4108,9 @@ define void @calli16_2() {
; MIPS64R5EB-NEXT: nop
; MIPS64R5EB-NEXT: ld $1, %got_disp(gv2i16)($gp)
; MIPS64R5EB-NEXT: sw $2, 0($1)
-; MIPS64R5EB-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload
-; MIPS64R5EB-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload
-; MIPS64R5EB-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EB-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload
+; MIPS64R5EB-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, 16
; MIPS64R5EB-NEXT: jr $ra
; MIPS64R5EB-NEXT: nop
;
@@ -4168,10 +4180,10 @@ define void @calli16_2() {
;
; MIPS64R5EL-LABEL: calli16_2:
; MIPS64R5EL: # %bb.0: # %entry
-; MIPS64R5EL-NEXT: daddiu $sp, $sp, -32
-; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5EL-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill
-; MIPS64R5EL-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, -16
+; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 16
+; MIPS64R5EL-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPS64R5EL-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill
; MIPS64R5EL-NEXT: .cfi_offset 31, -8
; MIPS64R5EL-NEXT: .cfi_offset 28, -16
; MIPS64R5EL-NEXT: lui $1, %hi(%neg(%gp_rel(calli16_2)))
@@ -4186,9 +4198,9 @@ define void @calli16_2() {
; MIPS64R5EL-NEXT: nop
; MIPS64R5EL-NEXT: ld $1, %got_disp(gv2i16)($gp)
; MIPS64R5EL-NEXT: sw $2, 0($1)
-; MIPS64R5EL-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload
-; MIPS64R5EL-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload
-; MIPS64R5EL-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EL-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload
+; MIPS64R5EL-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, 16
; MIPS64R5EL-NEXT: jr $ra
; MIPS64R5EL-NEXT: nop
entry:
@@ -4807,10 +4819,10 @@ define void @calli32_2() {
;
; MIPS64R5EB-LABEL: calli32_2:
; MIPS64R5EB: # %bb.0: # %entry
-; MIPS64R5EB-NEXT: daddiu $sp, $sp, -32
-; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5EB-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill
-; MIPS64R5EB-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, -16
+; MIPS64R5EB-NEXT: .cfi_def_cfa_offset 16
+; MIPS64R5EB-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPS64R5EB-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill
; MIPS64R5EB-NEXT: .cfi_offset 31, -8
; MIPS64R5EB-NEXT: .cfi_offset 28, -16
; MIPS64R5EB-NEXT: lui $1, %hi(%neg(%gp_rel(calli32_2)))
@@ -4826,9 +4838,9 @@ define void @calli32_2() {
; MIPS64R5EB-NEXT: nop
; MIPS64R5EB-NEXT: ld $1, %got_disp(gv2i32)($gp)
; MIPS64R5EB-NEXT: sd $2, 0($1)
-; MIPS64R5EB-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload
-; MIPS64R5EB-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload
-; MIPS64R5EB-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EB-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload
+; MIPS64R5EB-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPS64R5EB-NEXT: daddiu $sp, $sp, 16
; MIPS64R5EB-NEXT: jr $ra
; MIPS64R5EB-NEXT: nop
;
@@ -4862,10 +4874,10 @@ define void @calli32_2() {
;
; MIPS64R5EL-LABEL: calli32_2:
; MIPS64R5EL: # %bb.0: # %entry
-; MIPS64R5EL-NEXT: daddiu $sp, $sp, -32
-; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 32
-; MIPS64R5EL-NEXT: sd $ra, 24($sp) # 8-byte Folded Spill
-; MIPS64R5EL-NEXT: sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, -16
+; MIPS64R5EL-NEXT: .cfi_def_cfa_offset 16
+; MIPS64R5EL-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPS64R5EL-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill
; MIPS64R5EL-NEXT: .cfi_offset 31, -8
; MIPS64R5EL-NEXT: .cfi_offset 28, -16
; MIPS64R5EL-NEXT: lui $1, %hi(%neg(%gp_rel(calli32_2)))
@@ -4882,9 +4894,9 @@ define void @calli32_2() {
; MIPS64R5EL-NEXT: nop
; MIPS64R5EL-NEXT: ld $1, %got_disp(gv2i32)($gp)
; MIPS64R5EL-NEXT: sd $2, 0($1)
-; MIPS64R5EL-NEXT: ld $gp, 16($sp) # 8-byte Folded Reload
-; MIPS64R5EL-NEXT: ld $ra, 24($sp) # 8-byte Folded Reload
-; MIPS64R5EL-NEXT: daddiu $sp, $sp, 32
+; MIPS64R5EL-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload
+; MIPS64R5EL-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPS64R5EL-NEXT: daddiu $sp, $sp, 16
; MIPS64R5EL-NEXT: jr $ra
; MIPS64R5EL-NEXT: nop
entry:
>From 4e33b3ece58949161ea2bca11d28c55e933e2694 Mon Sep 17 00:00:00 2001
From: Xinhui Yang <cyan at cyano.uk>
Date: Wed, 15 Jan 2025 12:00:24 +0800
Subject: [PATCH 2/2] [MIPS][MSA] Handle UNDEFs in shuffle indices for VSHF
Currently VSHF does not handle UNDEF indices. However isSPLATI() is able
to handle undefs, which may pass indices with undefs to this function.
Adding a check to handle undefs in shuffle indices.
Also, shuffle mask widened from v2 vector types are guranteed to contain
UNDEFs. These shuffle lower logics can handle UNDEFs, so we just leave
it as is, except for VSHF, which we must use whatever necessary to fill
the UNDEFs.
---
llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 26 +++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 3519781fc9e0d7..fd2bb33f04b4b5 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -42,6 +42,7 @@
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <iterator>
#include <utility>
@@ -2968,8 +2969,14 @@ static SDValue lowerVECTOR_SHUFFLE_PCKOD(SDValue Op, EVT ResTy,
// if the type is v8i16 and all the indices are less than 8 then the second
// operand is unused and can be replaced with anything. We choose to replace it
// with the used operand since this reduces the number of instructions overall.
+//
+// NOTE: SPLATI shuffle masks may contain UNDEFs, since isSPLATI() treats
+// UNDEFs as same as SPLATI index.
+// For other instances we use the last valid index if UNDEF is
+// encountered.
static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
const SmallVector<int, 16> &Indices,
+ const bool isSPLATI,
SelectionDAG &DAG) {
SmallVector<SDValue, 16> Ops;
SDValue Op0;
@@ -2981,6 +2988,9 @@ static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
SDLoc DL(Op);
int ResTyNumElts = ResTy.getVectorNumElements();
+ assert(Indices[0] >= 0 &&
+ "shuffle mask starts with an UNDEF, which is not expected");
+
for (int i = 0; i < ResTyNumElts; ++i) {
// Idx == -1 means UNDEF
int Idx = Indices[i];
@@ -2990,9 +3000,17 @@ static SDValue lowerVECTOR_SHUFFLE_VSHF(SDValue Op, EVT ResTy,
if (ResTyNumElts <= Idx && Idx < ResTyNumElts * 2)
Using2ndVec = true;
}
-
- for (int Idx : Indices)
+ int LastValidIndex = 0;
+ for (size_t i = 0; i < Indices.size(); i++) {
+ int Idx = Indices[i];
+ if (Idx < 0) {
+ // Continue using splati index or use the last valid index.
+ Idx = isSPLATI ? Indices[0] : LastValidIndex;
+ } else {
+ LastValidIndex = Idx;
+ }
Ops.push_back(DAG.getTargetConstant(Idx, DL, MaskEltTy));
+ }
SDValue MaskVec = DAG.getBuildVector(MaskVecTy, DL, Ops);
@@ -3035,7 +3053,7 @@ SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
// splati.[bhwd] is preferable to the others but is matched from
// MipsISD::VSHF.
if (isVECTOR_SHUFFLE_SPLATI(Op, ResTy, Indices, DAG))
- return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG);
+ return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, true, DAG);
SDValue Result;
if ((Result = lowerVECTOR_SHUFFLE_ILVEV(Op, ResTy, Indices, DAG)))
return Result;
@@ -3051,7 +3069,7 @@ SDValue MipsSETargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
return Result;
if ((Result = lowerVECTOR_SHUFFLE_SHF(Op, ResTy, Indices, DAG)))
return Result;
- return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, DAG);
+ return lowerVECTOR_SHUFFLE_VSHF(Op, ResTy, Indices, false, DAG);
}
MachineBasicBlock *
More information about the llvm-commits
mailing list