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
38 changes: 38 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsLoongArch.td
Original file line number Diff line number Diff line change
Expand Up @@ -1192,4 +1192,42 @@ def int_loongarch_lasx_xvstelm_w
def int_loongarch_lasx_xvstelm_d
: VecInt<[], [llvm_v4i64_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
[IntrWriteMem, IntrArgMemOnly, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;

// LASX and LSX conversion
def int_loongarch_lasx_cast_128_s
: VecInt<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_cast_128_d
: VecInt<[llvm_v4f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_cast_128
: VecInt<[llvm_v4i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
def int_loongarch_lasx_concat_128_s
: VecInt<[llvm_v8f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_concat_128_d
: VecInt<[llvm_v4f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_concat_128
: VecInt<[llvm_v4i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_lo_s
: VecInt<[llvm_v4f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_lo_d
: VecInt<[llvm_v2f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_lo
: VecInt<[llvm_v2i64_ty], [llvm_v4i64_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_hi_s
: VecInt<[llvm_v4f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_hi_d
: VecInt<[llvm_v2f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_extract_128_hi
: VecInt<[llvm_v2i64_ty], [llvm_v4i64_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_lo_s
: VecInt<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_lo_d
: VecInt<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_lo
: VecInt<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_hi_s
: VecInt<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_hi_d
: VecInt<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
def int_loongarch_lasx_insert_128_hi
: VecInt<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
} // TargetPrefix = "loongarch"
5 changes: 5 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6612,6 +6612,11 @@ performINTRINSIC_WO_CHAINCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(LoongArchISD::VANY_NONZERO, DL, N->getValueType(0),
N->getOperand(1));
break;
case Intrinsic::loongarch_lasx_concat_128_s:
case Intrinsic::loongarch_lasx_concat_128_d:
case Intrinsic::loongarch_lasx_concat_128:
return DAG.getNode(ISD::CONCAT_VECTORS, DL, N->getValueType(0),
N->getOperand(1), N->getOperand(2));
}
return SDValue();
}
Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2088,6 +2088,37 @@ defm : subvector_subreg_lowering<LSX128, v2f64, LASX256, v4f64, 2, sub_128>;
defm : subvector_subreg_lowering<LSX128, v8i16, LASX256, v16i16, 8, sub_128>;
defm : subvector_subreg_lowering<LSX128, v16i8, LASX256, v32i8, 16, sub_128>;

// LASX and LSX conversion
def : Pat<(int_loongarch_lasx_cast_128_s (v4f32 LSX128:$src)),
(INSERT_SUBREG (IMPLICIT_DEF), LSX128:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_cast_128_d (v2f64 LSX128:$src)),
(INSERT_SUBREG (IMPLICIT_DEF), LSX128:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_cast_128 (v2i64 LSX128:$src)),
(INSERT_SUBREG (IMPLICIT_DEF), LSX128:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_lo_s (v8f32 LASX256:$src)),
(EXTRACT_SUBREG LASX256:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_lo_d (v4f64 LASX256:$src)),
(EXTRACT_SUBREG LASX256:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_lo (v4i64 LASX256:$src)),
(EXTRACT_SUBREG LASX256:$src, sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_hi_s (v8f32 LASX256:$src)),
(EXTRACT_SUBREG (XVPERMI_Q (IMPLICIT_DEF), LASX256:$src, 1), sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_hi_d (v4f64 LASX256:$src)),
(EXTRACT_SUBREG (XVPERMI_Q (IMPLICIT_DEF), LASX256:$src, 1), sub_128)>;
def : Pat<(int_loongarch_lasx_extract_128_hi (v4i64 LASX256:$src)),
(EXTRACT_SUBREG (XVPERMI_Q (IMPLICIT_DEF), LASX256:$src, 1), sub_128)>;
def : Pat<(int_loongarch_lasx_insert_128_lo_s (v8f32 LASX256:$src), (v4f32 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 48)>;
def : Pat<(int_loongarch_lasx_insert_128_lo_d (v4f64 LASX256:$src), (v2f64 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 48)>;
def : Pat<(int_loongarch_lasx_insert_128_lo (v4i64 LASX256:$src), (v2i64 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 48)>;
def : Pat<(int_loongarch_lasx_insert_128_hi_s (v8f32 LASX256:$src), (v4f32 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 2)>;
def : Pat<(int_loongarch_lasx_insert_128_hi_d (v4f64 LASX256:$src), (v2f64 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 2)>;
def : Pat<(int_loongarch_lasx_insert_128_hi (v4i64 LASX256:$src), (v2i64 LSX128:$lo)),
(XVPERMI_Q LASX256:$src, (INSERT_SUBREG (IMPLICIT_DEF), LSX128:$lo, sub_128), 2)>;
} // Predicates = [HasExtLASX]

/// Intrinsic pattern
Expand Down
303 changes: 303 additions & 0 deletions llvm/test/CodeGen/LoongArch/lasx/intrinsic-conversion.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s

declare <8 x float> @llvm.loongarch.lasx.cast.128.s(<4 x float>)

define void @lasx_cast_128_s(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_cast_128_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x float>, ptr %va
%b = call <8 x float> @llvm.loongarch.lasx.cast.128.s(<4 x float> %a)
store <8 x float> %b, ptr %vd
ret void
}

declare <4 x double> @llvm.loongarch.lasx.cast.128.d(<2 x double>)

define void @lasx_cast_128_d(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_cast_128_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <2 x double>, ptr %va
%b = call <4 x double> @llvm.loongarch.lasx.cast.128.d(<2 x double> %a)
store <4 x double> %b, ptr %vd
ret void
}

declare <4 x i64> @llvm.loongarch.lasx.cast.128(<2 x i64>)

define void @lasx_cast_128(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_cast_128:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <2 x i64>, ptr %va
%b = call <4 x i64> @llvm.loongarch.lasx.cast.128(<2 x i64> %a)
store <4 x i64> %b, ptr %vd
ret void
}

declare <8 x float> @llvm.loongarch.lasx.concat.128.s(<4 x float>, <4 x float>)

define void @lasx_concat_128_s(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_concat_128_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x float>, ptr %va
%b = load <4 x float>, ptr %vb
%c = call <8 x float> @llvm.loongarch.lasx.concat.128.s(<4 x float> %a, <4 x float> %b)
store <8 x float> %c, ptr %vd
ret void
}

declare <4 x double> @llvm.loongarch.lasx.concat.128.d(<2 x double>, <2 x double>)

define void @lasx_concat_128_d(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_concat_128_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <2 x double>, ptr %va
%b = load <2 x double>, ptr %vb
%c = call <4 x double> @llvm.loongarch.lasx.concat.128.d(<2 x double> %a, <2 x double> %b)
store <4 x double> %c, ptr %vd
ret void
}

declare <4 x i64> @llvm.loongarch.lasx.concat.128(<2 x i64>, <2 x i64>)

define void @lasx_concat_128(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_concat_128:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <2 x i64>, ptr %va
%b = load <2 x i64>, ptr %vb
%c = call <4 x i64> @llvm.loongarch.lasx.concat.128(<2 x i64> %a, <2 x i64> %b)
store <4 x i64> %c, ptr %vd
ret void
}

declare <4 x float> @llvm.loongarch.lasx.extract.128.lo.s(<8 x float>)

define void @lasx_extract_128_lo_s(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_lo_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <8 x float>, ptr %va
%c = call <4 x float> @llvm.loongarch.lasx.extract.128.lo.s(<8 x float> %a)
store <4 x float> %c, ptr %vd
ret void
}

declare <2 x double> @llvm.loongarch.lasx.extract.128.lo.d(<4 x double>)

define void @lasx_extract_128_lo_d(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_lo_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x double>, ptr %va
%c = call <2 x double> @llvm.loongarch.lasx.extract.128.lo.d(<4 x double> %a)
store <2 x double> %c, ptr %vd
ret void
}

declare <2 x i64> @llvm.loongarch.lasx.extract.128.lo(<4 x i64>)

define void @lasx_extract_128_lo(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_lo:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x i64>, ptr %va
%c = call <2 x i64> @llvm.loongarch.lasx.extract.128.lo(<4 x i64> %a)
store <2 x i64> %c, ptr %vd
ret void
}

declare <4 x float> @llvm.loongarch.lasx.extract.128.hi.s(<8 x float>)

define void @lasx_extract_128_hi_s(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_hi_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr0, 1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <8 x float>, ptr %va
%c = call <4 x float> @llvm.loongarch.lasx.extract.128.hi.s(<8 x float> %a)
store <4 x float> %c, ptr %vd
ret void
}

declare <2 x double> @llvm.loongarch.lasx.extract.128.hi.d(<4 x double>)

define void @lasx_extract_128_hi_d(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_hi_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr0, 1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x double>, ptr %va
%c = call <2 x double> @llvm.loongarch.lasx.extract.128.hi.d(<4 x double> %a)
store <2 x double> %c, ptr %vd
ret void
}

declare <2 x i64> @llvm.loongarch.lasx.extract.128.hi(<4 x i64>)

define void @lasx_extract_128_hi(ptr %vd, ptr %va) {
; CHECK-LABEL: lasx_extract_128_hi:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr0, 1
; CHECK-NEXT: vst $vr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x i64>, ptr %va
%c = call <2 x i64> @llvm.loongarch.lasx.extract.128.hi(<4 x i64> %a)
store <2 x i64> %c, ptr %vd
ret void
}

declare <8 x float> @llvm.loongarch.lasx.insert.128.lo.s(<8 x float>, <4 x float>)

define void @lasx_insert_128_lo_s(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_lo_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <8 x float>, ptr %va
%b = load <4 x float>, ptr %vb
%c = call <8 x float> @llvm.loongarch.lasx.insert.128.lo.s(<8 x float> %a, <4 x float> %b)
store <8 x float> %c, ptr %vd
ret void
}

declare <4 x double> @llvm.loongarch.lasx.insert.128.lo.d(<4 x double>, <2 x double>)

define void @lasx_insert_128_lo_d(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_lo_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x double>, ptr %va
%b = load <2 x double>, ptr %vb
%c = call <4 x double> @llvm.loongarch.lasx.insert.128.lo.d(<4 x double> %a, <2 x double> %b)
store <4 x double> %c, ptr %vd
ret void
}

declare <4 x i64> @llvm.loongarch.lasx.insert.128.lo(<4 x i64>, <2 x i64>)

define void @lasx_insert_128_lo(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_lo:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 48
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x i64>, ptr %va
%b = load <2 x i64>, ptr %vb
%c = call <4 x i64> @llvm.loongarch.lasx.insert.128.lo(<4 x i64> %a, <2 x i64> %b)
store <4 x i64> %c, ptr %vd
ret void
}

declare <8 x float> @llvm.loongarch.lasx.insert.128.hi.s(<8 x float>, <4 x float>)

define void @lasx_insert_128_hi_s(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_hi_s:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <8 x float>, ptr %va
%b = load <4 x float>, ptr %vb
%c = call <8 x float> @llvm.loongarch.lasx.insert.128.hi.s(<8 x float> %a, <4 x float> %b)
store <8 x float> %c, ptr %vd
ret void
}

declare <4 x double> @llvm.loongarch.lasx.insert.128.hi.d(<4 x double>, <2 x double>)

define void @lasx_insert_128_hi_d(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_hi_d:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x double>, ptr %va
%b = load <2 x double>, ptr %vb
%c = call <4 x double> @llvm.loongarch.lasx.insert.128.hi.d(<4 x double> %a, <2 x double> %b)
store <4 x double> %c, ptr %vd
ret void
}

declare <4 x i64> @llvm.loongarch.lasx.insert.128.hi(<4 x i64>, <2 x i64>)

define void @lasx_insert_128_hi(ptr %vd, ptr %va, ptr %vb) {
; CHECK-LABEL: lasx_insert_128_hi:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a1, 0
; CHECK-NEXT: vld $vr1, $a2, 0
; CHECK-NEXT: xvpermi.q $xr0, $xr1, 2
; CHECK-NEXT: xvst $xr0, $a0, 0
; CHECK-NEXT: ret
entry:
%a = load <4 x i64>, ptr %va
%b = load <2 x i64>, ptr %vb
%c = call <4 x i64> @llvm.loongarch.lasx.insert.128.hi(<4 x i64> %a, <2 x i64> %b)
store <4 x i64> %c, ptr %vd
ret void
}