Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2868,7 +2868,9 @@ LoongArchTargetLowering::lowerEXTRACT_VECTOR_ELT(SDValue Op,
// of MaskVec is Idx, the rest do not matter. ResVec[0] will hold the
// desired element.
SDValue IdxCp =
DAG.getNode(LoongArchISD::MOVGR2FR_W_LA64, DL, MVT::f32, Idx);
Subtarget.is64Bit()
? DAG.getNode(LoongArchISD::MOVGR2FR_W_LA64, DL, MVT::f32, Idx)
: DAG.getBitcast(MVT::f32, Idx);
SDValue IdxVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v8f32, IdxCp);
SDValue MaskVec =
DAG.getBitcast((VecTy == MVT::v4f64) ? MVT::v4i64 : VecTy, IdxVec);
Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1915,21 +1915,21 @@ def : Pat<(i64 (bitconvert (f64 (vector_extract v4f64:$xj, uimm2:$imm)))),
// Vector extraction with constant index.
foreach imm = 16...31 in {
defvar Imm = !and(imm, 15);
def : Pat<(i64 (vector_extract v32i8:$xj, imm)),
def : Pat<(GRLenVT (vector_extract v32i8:$xj, imm)),
(VPICKVE2GR_B (EXTRACT_SUBREG (XVPERMI_D v32i8:$xj, 14), sub_128),
Imm)>;
}
foreach imm = 8...15 in {
defvar Imm = !and(imm, 7);
def : Pat<(i64 (vector_extract v16i16:$xj, imm)),
def : Pat<(GRLenVT (vector_extract v16i16:$xj, imm)),
(VPICKVE2GR_H (EXTRACT_SUBREG (XVPERMI_D v16i16:$xj, 14), sub_128),
Imm)>;
}
def : Pat<(i64 (vector_extract v32i8:$xj, uimm4:$imm)),
def : Pat<(GRLenVT (vector_extract v32i8:$xj, uimm4:$imm)),
(VPICKVE2GR_B (EXTRACT_SUBREG v32i8:$xj, sub_128), uimm4:$imm)>;
def : Pat<(i64 (vector_extract v16i16:$xj, uimm3:$imm)),
def : Pat<(GRLenVT (vector_extract v16i16:$xj, uimm3:$imm)),
(VPICKVE2GR_H (EXTRACT_SUBREG v16i16:$xj, sub_128), uimm3:$imm)>;
def : Pat<(i64 (vector_extract v8i32:$xj, uimm3:$imm)),
def : Pat<(GRLenVT (vector_extract v8i32:$xj, uimm3:$imm)),
(XVPICKVE2GR_W v8i32:$xj, uimm3:$imm)>;
def : Pat<(i64 (vector_extract v4i64:$xj, uimm2:$imm)),
(XVPICKVE2GR_D v4i64:$xj, uimm2:$imm)>;
Expand Down
30 changes: 15 additions & 15 deletions llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2080,11 +2080,11 @@ def : Pat<(i64 (bitconvert (f64 (vector_extract v2f64:$vj, uimm1:$imm)))),
(VPICKVE2GR_D v2f64:$vj, uimm1:$imm)>;

// Vector extraction with constant index.
def : Pat<(i64 (vector_extract v16i8:$vj, uimm4:$imm)),
def : Pat<(GRLenVT (vector_extract v16i8:$vj, uimm4:$imm)),
(VPICKVE2GR_B v16i8:$vj, uimm4:$imm)>;
def : Pat<(i64 (vector_extract v8i16:$vj, uimm3:$imm)),
def : Pat<(GRLenVT (vector_extract v8i16:$vj, uimm3:$imm)),
(VPICKVE2GR_H v8i16:$vj, uimm3:$imm)>;
def : Pat<(i64 (vector_extract v4i32:$vj, uimm2:$imm)),
def : Pat<(GRLenVT (vector_extract v4i32:$vj, uimm2:$imm)),
(VPICKVE2GR_W v4i32:$vj, uimm2:$imm)>;
def : Pat<(i64 (vector_extract v2i64:$vj, uimm1:$imm)),
(VPICKVE2GR_D v2i64:$vj, uimm1:$imm)>;
Expand All @@ -2094,28 +2094,28 @@ def : Pat<(f64 (vector_extract v2f64:$vj, uimm1:$imm)),
(f64 (EXTRACT_SUBREG (VREPLVEI_D v2f64:$vj, uimm1:$imm), sub_64))>;

// Vector extraction with variable index.
def : Pat<(i64 (vector_extract v16i8:$vj, i64:$rk)),
def : Pat<(GRLenVT (vector_extract v16i8:$vj, GRLenVT:$rk)),
(SRAI_W (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_B v16i8:$vj,
i64:$rk),
GRLenVT:$rk),
sub_32)),
GPR), (i64 24))>;
def : Pat<(i64 (vector_extract v8i16:$vj, i64:$rk)),
GPR), (GRLenVT 24))>;
def : Pat<(GRLenVT (vector_extract v8i16:$vj, GRLenVT:$rk)),
(SRAI_W (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_H v8i16:$vj,
i64:$rk),
GRLenVT:$rk),
sub_32)),
GPR), (i64 16))>;
def : Pat<(i64 (vector_extract v4i32:$vj, i64:$rk)),
(COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_W v4i32:$vj, i64:$rk),
GPR), (GRLenVT 16))>;
def : Pat<(GRLenVT (vector_extract v4i32:$vj, GRLenVT:$rk)),
(COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG (VREPLVE_W v4i32:$vj, GRLenVT:$rk),
sub_32)),
GPR)>;
def : Pat<(i64 (vector_extract v2i64:$vj, i64:$rk)),
(COPY_TO_REGCLASS (f64 (EXTRACT_SUBREG (VREPLVE_D v2i64:$vj, i64:$rk),
sub_64)),
GPR)>;
def : Pat<(f32 (vector_extract v4f32:$vj, i64:$rk)),
(f32 (EXTRACT_SUBREG (VREPLVE_W v4f32:$vj, i64:$rk), sub_32))>;
def : Pat<(f64 (vector_extract v2f64:$vj, i64:$rk)),
(f64 (EXTRACT_SUBREG (VREPLVE_D v2f64:$vj, i64:$rk), sub_64))>;
def : Pat<(f32 (vector_extract v4f32:$vj, GRLenVT:$rk)),
(f32 (EXTRACT_SUBREG (VREPLVE_W v4f32:$vj, GRLenVT:$rk), sub_32))>;
def : Pat<(f64 (vector_extract v2f64:$vj, GRLenVT:$rk)),
(f64 (EXTRACT_SUBREG (VREPLVE_D v2f64:$vj, GRLenVT:$rk), sub_64))>;

// vselect
def : Pat<(v16i8 (vselect LSX128:$vd, (v16i8 (SplatPat_uimm8 uimm8:$imm)),
Expand Down
226 changes: 159 additions & 67 deletions llvm/test/CodeGen/LoongArch/lasx/ir-instruction/extractelement.ll
Original file line number Diff line number Diff line change
@@ -1,48 +1,79 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA32
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA64

define void @extract_32xi8(ptr %src, ptr %dst) nounwind {
; CHECK-LABEL: extract_32xi8:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvstelm.b $xr0, $a1, 0, 1
; CHECK-NEXT: ret
; LA32-LABEL: extract_32xi8:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: vpickve2gr.b $a0, $vr0, 1
; LA32-NEXT: st.b $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_32xi8:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvstelm.b $xr0, $a1, 0, 1
; LA64-NEXT: ret
%v = load volatile <32 x i8>, ptr %src
%e = extractelement <32 x i8> %v, i32 1
store i8 %e, ptr %dst
ret void
}

define void @extract_16xi16(ptr %src, ptr %dst) nounwind {
; CHECK-LABEL: extract_16xi16:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvstelm.h $xr0, $a1, 0, 1
; CHECK-NEXT: ret
; LA32-LABEL: extract_16xi16:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: vpickve2gr.h $a0, $vr0, 1
; LA32-NEXT: st.h $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_16xi16:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvstelm.h $xr0, $a1, 0, 1
; LA64-NEXT: ret
%v = load volatile <16 x i16>, ptr %src
%e = extractelement <16 x i16> %v, i32 1
store i16 %e, ptr %dst
ret void
}

define void @extract_8xi32(ptr %src, ptr %dst) nounwind {
; CHECK-LABEL: extract_8xi32:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvstelm.w $xr0, $a1, 0, 1
; CHECK-NEXT: ret
; LA32-LABEL: extract_8xi32:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
; LA32-NEXT: st.w $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_8xi32:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvstelm.w $xr0, $a1, 0, 1
; LA64-NEXT: ret
%v = load volatile <8 x i32>, ptr %src
%e = extractelement <8 x i32> %v, i32 1
store i32 %e, ptr %dst
ret void
}

define void @extract_4xi64(ptr %src, ptr %dst) nounwind {
; CHECK-LABEL: extract_4xi64:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvstelm.d $xr0, $a1, 0, 1
; CHECK-NEXT: ret
; LA32-LABEL: extract_4xi64:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
; LA32-NEXT: xvpickve2gr.w $a2, $xr0, 3
; LA32-NEXT: st.w $a2, $a1, 4
; LA32-NEXT: st.w $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_4xi64:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvstelm.d $xr0, $a1, 0, 1
; LA64-NEXT: ret
%v = load volatile <4 x i64>, ptr %src
%e = extractelement <4 x i64> %v, i32 1
store i64 %e, ptr %dst
Expand Down Expand Up @@ -74,58 +105,102 @@ define void @extract_4xdouble(ptr %src, ptr %dst) nounwind {
}

define void @extract_32xi8_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
; CHECK-LABEL: extract_32xi8_idx:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1
; CHECK-NEXT: movgr2fr.w $fa2, $a2
; CHECK-NEXT: xvshuf.b $xr0, $xr1, $xr0, $xr2
; CHECK-NEXT: xvstelm.b $xr0, $a1, 0, 0
; CHECK-NEXT: ret
; LA32-LABEL: extract_32xi8_idx:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: movgr2fr.w $fa1, $a2
; LA32-NEXT: xvpermi.q $xr2, $xr0, 1
; LA32-NEXT: xvshuf.b $xr0, $xr2, $xr0, $xr1
; LA32-NEXT: vpickve2gr.b $a0, $vr0, 0
; LA32-NEXT: st.b $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_32xi8_idx:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvpermi.q $xr1, $xr0, 1
; LA64-NEXT: movgr2fr.w $fa2, $a2
; LA64-NEXT: xvshuf.b $xr0, $xr1, $xr0, $xr2
; LA64-NEXT: xvstelm.b $xr0, $a1, 0, 0
; LA64-NEXT: ret
%v = load volatile <32 x i8>, ptr %src
%e = extractelement <32 x i8> %v, i32 %idx
store i8 %e, ptr %dst
ret void
}

define void @extract_16xi16_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
; CHECK-LABEL: extract_16xi16_idx:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1
; CHECK-NEXT: movgr2fr.w $fa2, $a2
; CHECK-NEXT: xvshuf.h $xr2, $xr1, $xr0
; CHECK-NEXT: xvstelm.h $xr2, $a1, 0, 0
; CHECK-NEXT: ret
; LA32-LABEL: extract_16xi16_idx:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: movgr2fr.w $fa1, $a2
; LA32-NEXT: xvpermi.q $xr2, $xr0, 1
; LA32-NEXT: xvshuf.h $xr1, $xr2, $xr0
; LA32-NEXT: vpickve2gr.h $a0, $vr1, 0
; LA32-NEXT: st.h $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_16xi16_idx:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvpermi.q $xr1, $xr0, 1
; LA64-NEXT: movgr2fr.w $fa2, $a2
; LA64-NEXT: xvshuf.h $xr2, $xr1, $xr0
; LA64-NEXT: xvstelm.h $xr2, $a1, 0, 0
; LA64-NEXT: ret
%v = load volatile <16 x i16>, ptr %src
%e = extractelement <16 x i16> %v, i32 %idx
store i16 %e, ptr %dst
ret void
}

define void @extract_8xi32_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
; CHECK-LABEL: extract_8xi32_idx:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvreplgr2vr.w $xr1, $a2
; CHECK-NEXT: xvperm.w $xr0, $xr0, $xr1
; CHECK-NEXT: xvstelm.w $xr0, $a1, 0, 0
; CHECK-NEXT: ret
; LA32-LABEL: extract_8xi32_idx:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: xvreplgr2vr.w $xr1, $a2
; LA32-NEXT: xvperm.w $xr0, $xr0, $xr1
; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
; LA32-NEXT: st.w $a0, $a1, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_8xi32_idx:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvreplgr2vr.w $xr1, $a2
; LA64-NEXT: xvperm.w $xr0, $xr0, $xr1
; LA64-NEXT: xvstelm.w $xr0, $a1, 0, 0
; LA64-NEXT: ret
%v = load volatile <8 x i32>, ptr %src
%e = extractelement <8 x i32> %v, i32 %idx
store i32 %e, ptr %dst
ret void
}

define void @extract_4xi64_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
; CHECK-LABEL: extract_4xi64_idx:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1
; CHECK-NEXT: movgr2fr.w $fa2, $a2
; CHECK-NEXT: xvshuf.d $xr2, $xr1, $xr0
; CHECK-NEXT: xvstelm.d $xr2, $a1, 0, 0
; CHECK-NEXT: ret
; LA32-LABEL: extract_4xi64_idx:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: add.w $a0, $a2, $a2
; LA32-NEXT: addi.w $a2, $a0, 1
; LA32-NEXT: xvreplgr2vr.w $xr1, $a2
; LA32-NEXT: xvperm.w $xr1, $xr0, $xr1
; LA32-NEXT: xvpickve2gr.w $a2, $xr1, 0
; LA32-NEXT: xvreplgr2vr.w $xr1, $a0
; LA32-NEXT: xvperm.w $xr0, $xr0, $xr1
; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
; LA32-NEXT: st.w $a0, $a1, 0
; LA32-NEXT: st.w $a2, $a1, 4
; LA32-NEXT: ret
;
; LA64-LABEL: extract_4xi64_idx:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvpermi.q $xr1, $xr0, 1
; LA64-NEXT: movgr2fr.w $fa2, $a2
; LA64-NEXT: xvshuf.d $xr2, $xr1, $xr0
; LA64-NEXT: xvstelm.d $xr2, $a1, 0, 0
; LA64-NEXT: ret
%v = load volatile <4 x i64>, ptr %src
%e = extractelement <4 x i64> %v, i32 %idx
store i64 %e, ptr %dst
Expand All @@ -147,28 +222,45 @@ define void @extract_8xfloat_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
}

define void @extract_4xdouble_idx(ptr %src, ptr %dst, i32 %idx) nounwind {
; CHECK-LABEL: extract_4xdouble_idx:
; CHECK: # %bb.0:
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvpermi.q $xr1, $xr0, 1
; CHECK-NEXT: movgr2fr.w $fa2, $a2
; CHECK-NEXT: xvshuf.d $xr2, $xr1, $xr0
; CHECK-NEXT: xvstelm.d $xr2, $a1, 0, 0
; CHECK-NEXT: ret
; LA32-LABEL: extract_4xdouble_idx:
; LA32: # %bb.0:
; LA32-NEXT: xvld $xr0, $a0, 0
; LA32-NEXT: movgr2fr.w $fa1, $a2
; LA32-NEXT: xvpermi.q $xr2, $xr0, 1
; LA32-NEXT: xvshuf.d $xr1, $xr2, $xr0
; LA32-NEXT: xvstelm.d $xr1, $a1, 0, 0
; LA32-NEXT: ret
;
; LA64-LABEL: extract_4xdouble_idx:
; LA64: # %bb.0:
; LA64-NEXT: xvld $xr0, $a0, 0
; LA64-NEXT: xvpermi.q $xr1, $xr0, 1
; LA64-NEXT: movgr2fr.w $fa2, $a2
; LA64-NEXT: xvshuf.d $xr2, $xr1, $xr0
; LA64-NEXT: xvstelm.d $xr2, $a1, 0, 0
; LA64-NEXT: ret
%v = load volatile <4 x double>, ptr %src
%e = extractelement <4 x double> %v, i32 %idx
store double %e, ptr %dst
ret void
}

define void @eliminate_frame_index(<8 x i32> %a) nounwind {
; CHECK-LABEL: eliminate_frame_index:
; CHECK: # %bb.0:
; CHECK-NEXT: addi.d $sp, $sp, -1040
; CHECK-NEXT: addi.d $a0, $sp, 524
; CHECK-NEXT: xvstelm.w $xr0, $a0, 0, 1
; CHECK-NEXT: addi.d $sp, $sp, 1040
; CHECK-NEXT: ret
; LA32-LABEL: eliminate_frame_index:
; LA32: # %bb.0:
; LA32-NEXT: addi.w $sp, $sp, -1040
; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
; LA32-NEXT: st.w $a0, $sp, 524
; LA32-NEXT: addi.w $sp, $sp, 1040
; LA32-NEXT: ret
;
; LA64-LABEL: eliminate_frame_index:
; LA64: # %bb.0:
; LA64-NEXT: addi.d $sp, $sp, -1040
; LA64-NEXT: addi.d $a0, $sp, 524
; LA64-NEXT: xvstelm.w $xr0, $a0, 0, 1
; LA64-NEXT: addi.d $sp, $sp, 1040
; LA64-NEXT: ret
%1 = alloca [32 x [8 x i32]]
%2 = getelementptr i8, ptr %1, i64 508
%b = extractelement <8 x i32> %a, i64 1
Expand Down
Loading