[llvm] [LoongArch][NFC] Add vector widening extends tests (PR #207315)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 23:03:12 PDT 2026


https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/207315

>From e08fe52ac19d40b0ab6bd9aa9a5523756f2cf127 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Thu, 2 Jul 2026 16:34:03 +0800
Subject: [PATCH] [LoongArch][NFC] Add vector widening extends tests

---
 llvm/test/CodeGen/LoongArch/lasx/xvexth.ll | 415 +++++++++++++++++++++
 llvm/test/CodeGen/LoongArch/lsx/vexth.ll   | 205 ++++++++++
 2 files changed, 620 insertions(+)
 create mode 100644 llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
 create mode 100644 llvm/test/CodeGen/LoongArch/lsx/vexth.ll

diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll b/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
new file mode 100644
index 0000000000000..17a2913c8bc5f
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/xvexth.ll
@@ -0,0 +1,415 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s
+
+define void @xvexth_h_b(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_h_b:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 3
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 6
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 15
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 7
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 8
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 9
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 10
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 11
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 12
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 13
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 15
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 15
+; CHECK-NEXT:    vext2xv.h.b $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <32 x i8>, ptr %a
+  %1 = shufflevector <32 x i8> %0, <32 x i8> poison,
+                     <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
+                                 i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+  %2 = sext <16 x i8> %1 to <16 x i16>
+  store <16 x i16> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_h_b_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_h_b_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 3
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 6
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 8
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 9
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 10
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 11
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 12
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 13
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 14
+; CHECK-NEXT:    vext2xv.h.b $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <32 x i8>, ptr %a
+  %1 = shufflevector <32 x i8> %0, <32 x i8> poison,
+                     <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 33,
+                                 i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 33>
+  %2 = sext <16 x i8> %1 to <16 x i16>
+  store <16 x i16> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_w_h(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_w_h:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 3
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 6
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 7
+; CHECK-NEXT:    vext2xv.w.h $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i16>, ptr %a
+  %1 = shufflevector <16 x i16> %0, <16 x i16> poison,
+                     <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
+  %2 = sext <8 x i16> %1 to <8 x i32>
+  store <8 x i32> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_w_h_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_w_h_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 3
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 6
+; CHECK-NEXT:    vext2xv.w.h $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i16>, ptr %a
+  %1 = shufflevector <16 x i16> %0, <16 x i16> poison,
+                     <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 16>
+  %2 = sext <8 x i16> %1 to <8 x i32>
+  store <8 x i32> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_d_w(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_d_w:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 3
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 1
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 6
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 2
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 7
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 3
+; CHECK-NEXT:    vext2xv.d.w $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i32>, ptr %a
+  %1 = shufflevector <8 x i32> %0, <8 x i32> poison,
+                     <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+  %2 = sext <4 x i32> %1 to <4 x i64>
+  store <4 x i64> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_d_w_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_d_w_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 3
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 1
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 6
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 2
+; CHECK-NEXT:    vext2xv.d.w $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i32>, ptr %a
+  %1 = shufflevector <8 x i32> %0, <8 x i32> poison,
+                     <4 x i32> <i32 2, i32 3, i32 6, i32 8>
+  %2 = sext <4 x i32> %1 to <4 x i64>
+  store <4 x i64> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_hu_bu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_hu_bu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 3
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 6
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 15
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 7
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 8
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 9
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 10
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 11
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 12
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 13
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 15
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 15
+; CHECK-NEXT:    vext2xv.hu.bu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <32 x i8>, ptr %a
+  %1 = shufflevector <32 x i8> %0, <32 x i8> poison,
+                     <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,
+                                 i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
+  %2 = zext <16 x i8> %1 to <16 x i16>
+  store <16 x i16> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_hu_bu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_hu_bu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 3
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 6
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 8
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 8
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 9
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 9
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 10
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 10
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 11
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 11
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 12
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 12
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 13
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 13
+; CHECK-NEXT:    vpickve2gr.b $a0, $vr0, 14
+; CHECK-NEXT:    vinsgr2vr.b $vr1, $a0, 14
+; CHECK-NEXT:    vext2xv.hu.bu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <32 x i8>, ptr %a
+  %1 = shufflevector <32 x i8> %0, <32 x i8> poison,
+                     <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 33,
+                                 i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 33>
+  %2 = zext <16 x i8> %1 to <16 x i16>
+  store <16 x i16> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_wu_hu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_wu_hu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 3
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 6
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 7
+; CHECK-NEXT:    vext2xv.wu.hu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i16>, ptr %a
+  %1 = shufflevector <16 x i16> %0, <16 x i16> poison,
+                     <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
+  %2 = zext <8 x i16> %1 to <8 x i32>
+  store <8 x i32> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_wu_hu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_wu_hu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 0
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 1
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 2
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 7
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 3
+; CHECK-NEXT:    xvpermi.d $xr0, $xr0, 14
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 4
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 4
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 5
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 5
+; CHECK-NEXT:    vpickve2gr.h $a0, $vr0, 6
+; CHECK-NEXT:    vinsgr2vr.h $vr1, $a0, 6
+; CHECK-NEXT:    vext2xv.wu.hu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i16>, ptr %a
+  %1 = shufflevector <16 x i16> %0, <16 x i16> poison,
+                     <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 16>
+  %2 = zext <8 x i16> %1 to <8 x i32>
+  store <8 x i32> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_du_wu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_du_wu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 3
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 1
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 6
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 2
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 7
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 3
+; CHECK-NEXT:    vext2xv.du.wu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i32>, ptr %a
+  %1 = shufflevector <8 x i32> %0, <8 x i32> poison,
+                     <4 x i32> <i32 2, i32 3, i32 6, i32 7>
+  %2 = zext <4 x i32> %1 to <4 x i64>
+  store <4 x i64> %2, ptr %r
+  ret void
+}
+
+define void @xvexth_du_wu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: xvexth_du_wu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    xvld $xr0, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 2
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 0
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 3
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 1
+; CHECK-NEXT:    xvpickve2gr.w $a0, $xr0, 6
+; CHECK-NEXT:    vinsgr2vr.w $vr1, $a0, 2
+; CHECK-NEXT:    vext2xv.du.wu $xr0, $xr1
+; CHECK-NEXT:    xvst $xr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i32>, ptr %a
+  %1 = shufflevector <8 x i32> %0, <8 x i32> poison,
+                     <4 x i32> <i32 2, i32 3, i32 6, i32 8>
+  %2 = zext <4 x i32> %1 to <4 x i64>
+  store <4 x i64> %2, ptr %r
+  ret void
+}
diff --git a/llvm/test/CodeGen/LoongArch/lsx/vexth.ll b/llvm/test/CodeGen/LoongArch/lsx/vexth.ll
new file mode 100644
index 0000000000000..92ff7df93a4f2
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lsx/vexth.ll
@@ -0,0 +1,205 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lsx < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --mattr=+lsx < %s | FileCheck %s
+
+define void @vexth_h_b(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_h_b:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vbsrl.v $vr0, $vr0, 8
+; CHECK-NEXT:    vslti.b $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i8>, ptr %a
+  %1 = shufflevector <16 x i8> %0, <16 x i8> poison,
+                     <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  %2 = sext <8 x i8> %1 to <8 x i16>
+  store <8 x i16> %2, ptr %r
+  ret void
+}
+
+define void @vexth_h_b_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_h_b_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vbsrl.v $vr0, $vr0, 8
+; CHECK-NEXT:    vslti.b $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.b $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i8>, ptr %a
+  %1 = shufflevector <16 x i8> %0, <16 x i8> poison,
+                     <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 16>
+  %2 = sext <8 x i8> %1 to <8 x i16>
+  store <8 x i16> %2, ptr %r
+  ret void
+}
+
+define void @vexth_w_h(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_w_h:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vbsrl.v $vr0, $vr0, 8
+; CHECK-NEXT:    vslti.h $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i16>, ptr %a
+  %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  %2 = sext <4 x i16> %1 to <4 x i32>
+  store <4 x i32> %2, ptr %r
+  ret void
+}
+
+define void @vexth_w_h_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_w_h_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vbsrl.v $vr0, $vr0, 8
+; CHECK-NEXT:    vslti.h $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.h $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i16>, ptr %a
+  %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 8>
+  %2 = sext <4 x i16> %1 to <4 x i32>
+  store <4 x i32> %2, ptr %r
+  ret void
+}
+
+define void @vexth_d_w(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_d_w:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vshuf4i.w $vr0, $vr0, 14
+; CHECK-NEXT:    vslti.w $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <4 x i32>, ptr %a
+  %1 = shufflevector <4 x i32> %0, <4 x i32> poison, <2 x i32> <i32 2, i32 3>
+  %2 = sext <2 x i32> %1 to <2 x i64>
+  store <2 x i64> %2, ptr %r
+  ret void
+}
+
+define void @vexth_d_w_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_d_w_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vshuf4i.w $vr0, $vr0, 14
+; CHECK-NEXT:    vslti.w $vr1, $vr0, 0
+; CHECK-NEXT:    vilvl.w $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <4 x i32>, ptr %a
+  %1 = shufflevector <4 x i32> %0, <4 x i32> poison, <2 x i32> <i32 2, i32 4>
+  %2 = sext <2 x i32> %1 to <2 x i64>
+  store <2 x i64> %2, ptr %r
+  ret void
+}
+
+define void @vexth_hu_bu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_hu_bu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.b $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i8>, ptr %a
+  %1 = shufflevector <16 x i8> %0, <16 x i8> poison,
+                     <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+  %2 = zext <8 x i8> %1 to <8 x i16>
+  store <8 x i16> %2, ptr %r
+  ret void
+}
+
+define void @vexth_hu_bu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_hu_bu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.b $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <16 x i8>, ptr %a
+  %1 = shufflevector <16 x i8> %0, <16 x i8> poison,
+                     <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 16>
+  %2 = zext <8 x i8> %1 to <8 x i16>
+  store <8 x i16> %2, ptr %r
+  ret void
+}
+
+define void @vexth_wu_hu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_wu_hu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.h $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i16>, ptr %a
+  %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+  %2 = zext <4 x i16> %1 to <4 x i32>
+  store <4 x i32> %2, ptr %r
+  ret void
+}
+
+define void @vexth_wu_hu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_wu_hu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.h $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <8 x i16>, ptr %a
+  %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 8>
+  %2 = zext <4 x i16> %1 to <4 x i32>
+  store <4 x i32> %2, ptr %r
+  ret void
+}
+
+define void @vexth_du_wu(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_du_wu:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.w $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <4 x i32>, ptr %a
+  %1 = shufflevector <4 x i32> %0, <4 x i32> poison, <2 x i32> <i32 2, i32 3>
+  %2 = zext <2 x i32> %1 to <2 x i64>
+  store <2 x i64> %2, ptr %r
+  ret void
+}
+
+define void @vexth_du_wu_poison(ptr %a, ptr %r) nounwind {
+; CHECK-LABEL: vexth_du_wu_poison:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    vld $vr0, $a0, 0
+; CHECK-NEXT:    vrepli.b $vr1, 0
+; CHECK-NEXT:    vilvh.w $vr0, $vr1, $vr0
+; CHECK-NEXT:    vst $vr0, $a1, 0
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <4 x i32>, ptr %a
+  %1 = shufflevector <4 x i32> %0, <4 x i32> poison, <2 x i32> <i32 2, i32 4>
+  %2 = zext <2 x i32> %1 to <2 x i64>
+  store <2 x i64> %2, ptr %r
+  ret void
+}



More information about the llvm-commits mailing list