[llvm] [LoongArch] Legalize LASX truncate with XVPICKEV instruction (PR #202485)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 9 06:19:11 PDT 2026
https://github.com/lrzlin updated https://github.com/llvm/llvm-project/pull/202485
>From 6fe72619cd4ebf41033dd0278f9f059e4372ec0c Mon Sep 17 00:00:00 2001
From: Lin Runze <linrunze at loongson.cn>
Date: Thu, 4 Jun 2026 19:01:49 +0800
Subject: [PATCH 1/2] [LoongArch][NFC] Add truncate tests for LASX
---
.../LoongArch/lasx/vec-trunc-combine.ll | 769 ++++++++++++++++++
1 file changed, 769 insertions(+)
create mode 100644 llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll b/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
new file mode 100644
index 0000000000000..77136eb165149
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
@@ -0,0 +1,769 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx %s -o - | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx %s -o - | FileCheck %s --check-prefix=LA64
+
+define <4 x i8> @test_trunc_v4i16_to_v4i8(<4 x i16> %arg) {
+; LA32-LABEL: test_trunc_v4i16_to_v4i8:
+; LA32: # %bb.0:
+; LA32-NEXT: vpickev.b $vr0, $vr0, $vr0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i16_to_v4i8:
+; LA64: # %bb.0:
+; LA64-NEXT: vpickev.b $vr0, $vr0, $vr0
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i16> %arg to <4 x i8>
+ ret <4 x i8> %trunc
+}
+
+define <4 x i8> @test_trunc_v4i32_to_v4i8(<4 x i32> %arg) {
+; LA32-LABEL: test_trunc_v4i32_to_v4i8:
+; LA32: # %bb.0:
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI1_0)
+; LA32-NEXT: vld $vr1, $a0, %pc_lo12(.LCPI1_0)
+; LA32-NEXT: vshuf.b $vr0, $vr0, $vr0, $vr1
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i32_to_v4i8:
+; LA64: # %bb.0:
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI1_0)
+; LA64-NEXT: vld $vr1, $a0, %pc_lo12(.LCPI1_0)
+; LA64-NEXT: vshuf.b $vr0, $vr0, $vr0, $vr1
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i32> %arg to <4 x i8>
+ ret <4 x i8> %trunc
+}
+
+define <4 x i16> @test_trunc_v4i32_to_v4i16(<4 x i32> %arg) {
+; LA32-LABEL: test_trunc_v4i32_to_v4i16:
+; LA32: # %bb.0:
+; LA32-NEXT: vpickev.h $vr0, $vr0, $vr0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i32_to_v4i16:
+; LA64: # %bb.0:
+; LA64-NEXT: vpickev.h $vr0, $vr0, $vr0
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i32> %arg to <4 x i16>
+ ret <4 x i16> %trunc
+}
+
+define <4 x i8> @test_trunc_v4i64_to_v4i8(<4 x i64> %arg) {
+; LA32-LABEL: test_trunc_v4i64_to_v4i8:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 3
+; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i64_to_v4i8:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 3
+; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i64> %arg to <4 x i8>
+ ret <4 x i8> %trunc
+}
+
+define <4 x i16> @test_trunc_v4i64_to_v4i16(<4 x i64> %arg) {
+; LA32-LABEL: test_trunc_v4i64_to_v4i16:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i64_to_v4i16:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i64> %arg to <4 x i16>
+ ret <4 x i16> %trunc
+}
+
+define <4 x i32> @test_trunc_v4i64_to_v4i32(<4 x i64> %arg) {
+; LA32-LABEL: test_trunc_v4i64_to_v4i32:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v4i64_to_v4i32:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <4 x i64> %arg to <4 x i32>
+ ret <4 x i32> %trunc
+}
+
+define <8 x i8> @test_trunc_v8i32_to_v8i8(<8 x i32> %arg) {
+; LA32-LABEL: test_trunc_v8i32_to_v8i8:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 7
+; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v8i32_to_v8i8:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 3
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 4
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 5
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 6
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 7
+; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <8 x i32> %arg to <8 x i8>
+ ret <8 x i8> %trunc
+}
+
+define <8 x i16> @test_trunc_v8i32_to_v8i16(<8 x i32> %arg) {
+; LA32-LABEL: test_trunc_v8i32_to_v8i16:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 7
+; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v8i32_to_v8i16:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 4
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 5
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 6
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 7
+; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <8 x i32> %arg to <8 x i16>
+ ret <8 x i16> %trunc
+}
+
+define <8 x i8> @test_trunc_v8i64_to_v8i8(<8 x i64> %arg) {
+; LA32-LABEL: test_trunc_v8i64_to_v8i8:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 7
+; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v8i64_to_v8i8:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 4
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 5
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 6
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 7
+; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: ret
+ %trunc = trunc <8 x i64> %arg to <8 x i8>
+ ret <8 x i8> %trunc
+}
+
+define <8 x i16> @test_trunc_v8i64_to_v8i16(<8 x i64> %arg) {
+; LA32-LABEL: test_trunc_v8i64_to_v8i16:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v8i64_to_v8i16:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: ret
+ %trunc = trunc <8 x i64> %arg to <8 x i16>
+ ret <8 x i16> %trunc
+}
+
+define <8 x i32> @test_trunc_v8i64_to_v8i32(<8 x i64> %arg) {
+; LA32-LABEL: test_trunc_v8i64_to_v8i32:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA32-NEXT: xvpermi.q $xr1, $xr2, 2
+; LA32-NEXT: xvori.b $xr0, $xr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v8i64_to_v8i32:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA64-NEXT: xvpermi.q $xr1, $xr2, 2
+; LA64-NEXT: xvori.b $xr0, $xr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <8 x i64> %arg to <8 x i32>
+ ret <8 x i32> %trunc
+}
+
+define <16 x i8> @test_trunc_v16i32_to_v16i8(<16 x i32> %arg) {
+; LA32-LABEL: test_trunc_v16i32_to_v16i8:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 7
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 8
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 1
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 9
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 10
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 3
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 11
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 12
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 5
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 13
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 14
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 7
+; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 15
+; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v16i32_to_v16i8:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 4
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 5
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 6
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 7
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 8
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 9
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 10
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 11
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 12
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 5
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 13
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 14
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 7
+; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 15
+; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: ret
+ %trunc = trunc <16 x i32> %arg to <16 x i8>
+ ret <16 x i8> %trunc
+}
+
+define <16 x i16> @test_trunc_v16i32_to_v16i16(<16 x i32> %arg) {
+; LA32-LABEL: test_trunc_v16i32_to_v16i16:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 1
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 3
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 5
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 7
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 7
+; LA32-NEXT: xvpermi.q $xr1, $xr2, 2
+; LA32-NEXT: xvori.b $xr0, $xr1, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v16i32_to_v16i16:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 5
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 7
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 4
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 5
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 6
+; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
+; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 7
+; LA64-NEXT: xvpermi.q $xr1, $xr2, 2
+; LA64-NEXT: xvori.b $xr0, $xr1, 0
+; LA64-NEXT: ret
+ %trunc = trunc <16 x i32> %arg to <16 x i16>
+ ret <16 x i16> %trunc
+}
+
+define <16 x i8> @test_trunc_v16i64_to_v16i8(<16 x i64> %arg) {
+; LA32-LABEL: test_trunc_v16i64_to_v16i8:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 7
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 8
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 9
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 10
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 11
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 12
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 13
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 14
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
+; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 15
+; LA32-NEXT: vori.b $vr0, $vr4, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v16i64_to_v16i8:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 4
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 5
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 6
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 7
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 8
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 9
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 10
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 11
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 12
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 13
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 14
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
+; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 15
+; LA64-NEXT: vori.b $vr0, $vr4, 0
+; LA64-NEXT: ret
+ %trunc = trunc <16 x i64> %arg to <16 x i8>
+ ret <16 x i8> %trunc
+}
+
+define <16 x i16> @test_trunc_v16i64_to_v16i16(<16 x i64> %arg) {
+; LA32-LABEL: test_trunc_v16i64_to_v16i16:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
+; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 7
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA32-NEXT: xvpermi.q $xr2, $xr4, 2
+; LA32-NEXT: xvori.b $xr0, $xr2, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v16i64_to_v16i16:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 4
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 5
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 6
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
+; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 7
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
+; LA64-NEXT: xvpermi.q $xr2, $xr4, 2
+; LA64-NEXT: xvori.b $xr0, $xr2, 0
+; LA64-NEXT: ret
+ %trunc = trunc <16 x i64> %arg to <16 x i16>
+ ret <16 x i16> %trunc
+}
+
+define <16 x i32> @test_trunc_v16i64_to_v16i32(<16 x i64> %arg) {
+; LA32-LABEL: test_trunc_v16i64_to_v16i32:
+; LA32: # %bb.0:
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
+; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
+; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
+; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
+; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
+; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
+; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
+; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
+; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 3
+; LA32-NEXT: xvpermi.q $xr4, $xr5, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
+; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
+; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
+; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
+; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 3
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
+; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA32-NEXT: xvpermi.q $xr1, $xr0, 2
+; LA32-NEXT: xvori.b $xr0, $xr4, 0
+; LA32-NEXT: ret
+;
+; LA64-LABEL: test_trunc_v16i64_to_v16i32:
+; LA64: # %bb.0:
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
+; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
+; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
+; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
+; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
+; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
+; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
+; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
+; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 3
+; LA64-NEXT: xvpermi.q $xr4, $xr5, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
+; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
+; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
+; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
+; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 3
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
+; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
+; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
+; LA64-NEXT: xvpermi.q $xr1, $xr0, 2
+; LA64-NEXT: xvori.b $xr0, $xr4, 0
+; LA64-NEXT: ret
+ %trunc = trunc <16 x i64> %arg to <16 x i32>
+ ret <16 x i32> %trunc
+}
>From 6e43cd102d8412c87b8d0d25384e6b3d024dc47d Mon Sep 17 00:00:00 2001
From: Lin Runze <linrunze at loongson.cn>
Date: Sat, 6 Jun 2026 17:26:42 +0800
Subject: [PATCH 2/2] [LoongArch] Legalize LASX truncate with XVPICKEV
instruction
---
.../LoongArch/LoongArchISelLowering.cpp | 19 +
.../LoongArch/LoongArchLASXInstrInfo.td | 19 +
.../LoongArch/lasx/vec-trunc-combine.ll | 674 +++---------------
.../test/CodeGen/LoongArch/lasx/vxi1-masks.ll | 71 +-
llvm/test/CodeGen/LoongArch/lasx/xvmskcond.ll | 51 +-
llvm/test/CodeGen/LoongArch/pr177863.ll | 24 +-
6 files changed, 203 insertions(+), 655 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 561064b3e1090..02e341f26fd54 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -493,6 +493,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, VT, Legal);
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Legal);
}
+ for (MVT VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
+ setOperationAction(ISD::TRUNCATE, VT, Legal);
}
// Set DAG combine for LA32 and LA64.
@@ -3813,6 +3815,10 @@ SDValue LoongArchTargetLowering::lowerCONCAT_VECTORS(SDValue Op,
MVT ResVT = Op.getSimpleValueType();
assert(ResVT.is256BitVector() && Op.getNumOperands() == 2);
+ if (Op.getOperand(0).getOpcode() == ISD::TRUNCATE &&
+ Op.getOperand(1).getOpcode() == ISD::TRUNCATE)
+ return Op;
+
unsigned NumOperands = Op.getNumOperands();
unsigned NumFreezeUndef = 0;
unsigned NumZero = 0;
@@ -5766,6 +5772,19 @@ void LoongArchTargetLowering::ReplaceNodeResults(
unsigned WidenNumElts = WidenVT.getVectorNumElements();
unsigned InBits = InVT.getSizeInBits();
+ if (InBits == 512 && WidenVT.is128BitVector()) {
+ InVT = MVT::getVectorVT(MVT::getIntegerVT(256 / MinElts), MinElts);
+ In = DAG.getNode(N->getOpcode(), DL, InVT, In);
+ InBits = 256;
+ }
+
+ if (InBits == 256 && WidenVT.is128BitVector()) {
+ InVT = MVT::getVectorVT(MVT::getIntegerVT(128 / MinElts), MinElts);
+ In = DAG.getNode(N->getOpcode(), DL, InVT, In);
+ InBits = 128;
+ InEltVT = InVT.getVectorElementType();
+ }
+
if ((128 % InBits) == 0 && WidenVT.is128BitVector()) {
if ((InEltVT.getSizeInBits() % EltVT.getSizeInBits()) == 0) {
int Scale = InEltVT.getSizeInBits() / EltVT.getSizeInBits();
diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 0fb2b1d332f60..24e68822dd7dc 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -2120,6 +2120,25 @@ def : Pat<(v4i32(fp_to_uint v4f64:$vj)),
(XVFTINTRZ_LU_D v4f64:$vj)),
sub_128)>;
+// truncate
+def : Pat<(v4i32 (trunc v4i64:$xj)),
+ (EXTRACT_SUBREG(XVPERMI_D(XVPICKEV_W v4i64:$xj, v4i64:$xj), 216), sub_128)>;
+
+def : Pat<(v8i16 (trunc v8i32:$xj)),
+ (EXTRACT_SUBREG(XVPERMI_D(XVPICKEV_H v8i32:$xj, v8i32:$xj), 216), sub_128)>;
+
+def : Pat<(v16i8 (trunc v16i16:$xj)),
+ (EXTRACT_SUBREG(XVPERMI_D(XVPICKEV_B v16i16:$xj, v16i16:$xj), 216), sub_128)>;
+
+def : Pat<(v8i32 (concat_vectors (v4i32 (trunc v4i64:$xj)), (v4i32 (trunc v4i64:$xk)))),
+ (XVPERMI_D(XVPICKEV_W v4i64:$xk, v4i64:$xj), 216)>;
+
+def : Pat<(v16i16 (concat_vectors (v8i16 (trunc v8i32:$xj)), (v8i16 (trunc v8i32:$xk)))),
+ (XVPERMI_D(XVPICKEV_H v8i32:$xk, v8i32:$xj), 216)>;
+
+def : Pat<(v32i8 (concat_vectors (v16i8 (trunc v16i16:$xj)), (v16i8 (trunc v16i16:$xk)))),
+ (XVPERMI_D(XVPICKEV_B v16i16:$xk, v16i16:$xj), 216)>;
+
// XVAVG_{B/H/W/D/BU/HU/WU/DU}, XVAVGR_{B/H/W/D/BU/HU/WU/DU}
defm : PatXrXr<avgfloors, "XVAVG">;
defm : PatXrXr<avgceils, "XVAVGR">;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll b/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
index 77136eb165149..7ec3cf05e63e7 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vec-trunc-combine.ll
@@ -51,28 +51,20 @@ define <4 x i16> @test_trunc_v4i32_to_v4i16(<4 x i32> %arg) {
define <4 x i8> @test_trunc_v4i64_to_v4i8(<4 x i64> %arg) {
; LA32-LABEL: test_trunc_v4i64_to_v4i8:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 3
-; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_0)
+; LA32-NEXT: vld $vr1, $a0, %pc_lo12(.LCPI3_0)
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vshuf.b $vr0, $vr0, $vr0, $vr1
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v4i64_to_v4i8:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 3
-; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: pcalau12i $a0, %pc_hi20(.LCPI3_0)
+; LA64-NEXT: vld $vr1, $a0, %pc_lo12(.LCPI3_0)
+; LA64-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: vshuf.b $vr0, $vr0, $vr0, $vr1
; LA64-NEXT: ret
%trunc = trunc <4 x i64> %arg to <4 x i8>
ret <4 x i8> %trunc
@@ -81,28 +73,16 @@ define <4 x i8> @test_trunc_v4i64_to_v4i8(<4 x i64> %arg) {
define <4 x i16> @test_trunc_v4i64_to_v4i16(<4 x i64> %arg) {
; LA32-LABEL: test_trunc_v4i64_to_v4i16:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vpickev.h $vr0, $vr0, $vr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v4i64_to_v4i16:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: vpickev.h $vr0, $vr0, $vr0
; LA64-NEXT: ret
%trunc = trunc <4 x i64> %arg to <4 x i16>
ret <4 x i16> %trunc
@@ -111,28 +91,16 @@ define <4 x i16> @test_trunc_v4i64_to_v4i16(<4 x i64> %arg) {
define <4 x i32> @test_trunc_v4i64_to_v4i32(<4 x i64> %arg) {
; LA32-LABEL: test_trunc_v4i64_to_v4i32:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v4i64_to_v4i32:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA64-NEXT: ret
%trunc = trunc <4 x i64> %arg to <4 x i32>
ret <4 x i32> %trunc
@@ -141,44 +109,16 @@ define <4 x i32> @test_trunc_v4i64_to_v4i32(<4 x i64> %arg) {
define <8 x i8> @test_trunc_v8i32_to_v8i8(<8 x i32> %arg) {
; LA32-LABEL: test_trunc_v8i32_to_v8i8:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA32-NEXT: vinsgr2vr.b $vr1, $a0, 7
-; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vpickev.b $vr0, $vr0, $vr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v8i32_to_v8i8:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 3
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 4
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 5
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 6
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA64-NEXT: vinsgr2vr.b $vr1, $a0, 7
-; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: vpickev.b $vr0, $vr0, $vr0
; LA64-NEXT: ret
%trunc = trunc <8 x i32> %arg to <8 x i8>
ret <8 x i8> %trunc
@@ -187,44 +127,16 @@ define <8 x i8> @test_trunc_v8i32_to_v8i8(<8 x i32> %arg) {
define <8 x i16> @test_trunc_v8i32_to_v8i16(<8 x i32> %arg) {
; LA32-LABEL: test_trunc_v8i32_to_v8i16:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 7
-; LA32-NEXT: vori.b $vr0, $vr1, 0
+; LA32-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v8i32_to_v8i16:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 4
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 5
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 6
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 7
-; LA64-NEXT: vori.b $vr0, $vr1, 0
+; LA64-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA64-NEXT: ret
%trunc = trunc <8 x i32> %arg to <8 x i16>
ret <8 x i16> %trunc
@@ -233,44 +145,20 @@ define <8 x i16> @test_trunc_v8i32_to_v8i16(<8 x i32> %arg) {
define <8 x i8> @test_trunc_v8i64_to_v8i8(<8 x i64> %arg) {
; LA32-LABEL: test_trunc_v8i64_to_v8i8:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vpickev.b $vr0, $vr0, $vr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v8i64_to_v8i8:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: vpickev.b $vr0, $vr0, $vr0
; LA64-NEXT: ret
%trunc = trunc <8 x i64> %arg to <8 x i8>
ret <8 x i8> %trunc
@@ -279,44 +167,20 @@ define <8 x i8> @test_trunc_v8i64_to_v8i8(<8 x i64> %arg) {
define <8 x i16> @test_trunc_v8i64_to_v8i16(<8 x i64> %arg) {
; LA32-LABEL: test_trunc_v8i64_to_v8i16:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v8i64_to_v8i16:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.h $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA64-NEXT: ret
%trunc = trunc <8 x i64> %arg to <8 x i16>
ret <8 x i16> %trunc
@@ -325,46 +189,14 @@ define <8 x i16> @test_trunc_v8i64_to_v8i16(<8 x i64> %arg) {
define <8 x i32> @test_trunc_v8i64_to_v8i32(<8 x i64> %arg) {
; LA32-LABEL: test_trunc_v8i64_to_v8i32:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA32-NEXT: xvpermi.q $xr1, $xr2, 2
-; LA32-NEXT: xvori.b $xr0, $xr1, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v8i64_to_v8i32:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA64-NEXT: xvpermi.q $xr1, $xr2, 2
-; LA64-NEXT: xvori.b $xr0, $xr1, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
; LA64-NEXT: ret
%trunc = trunc <8 x i64> %arg to <8 x i32>
ret <8 x i32> %trunc
@@ -373,76 +205,20 @@ define <8 x i32> @test_trunc_v8i64_to_v8i32(<8 x i64> %arg) {
define <16 x i8> @test_trunc_v16i32_to_v16i8(<16 x i32> %arg) {
; LA32-LABEL: test_trunc_v16i32_to_v16i8:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 1
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 3
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 5
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 7
-; LA32-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; LA32-NEXT: vori.b $vr0, $vr2, 0
+; LA32-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.b $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v16i32_to_v16i8:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 5
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 7
-; LA64-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; LA64-NEXT: vori.b $vr0, $vr2, 0
+; LA64-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.b $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA64-NEXT: ret
%trunc = trunc <16 x i32> %arg to <16 x i8>
ret <16 x i8> %trunc
@@ -451,78 +227,14 @@ define <16 x i8> @test_trunc_v16i32_to_v16i8(<16 x i32> %arg) {
define <16 x i16> @test_trunc_v16i32_to_v16i16(<16 x i32> %arg) {
; LA32-LABEL: test_trunc_v16i32_to_v16i16:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 1
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 3
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 5
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 7
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA32-NEXT: vinsgr2vr.h $vr1, $a0, 7
-; LA32-NEXT: xvpermi.q $xr1, $xr2, 2
-; LA32-NEXT: xvori.b $xr0, $xr1, 0
+; LA32-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v16i32_to_v16i16:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 5
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA64-NEXT: xvpickve2gr.w $a0, $xr1, 7
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 3
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 4
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 5
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 6
-; LA64-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; LA64-NEXT: vinsgr2vr.h $vr1, $a0, 7
-; LA64-NEXT: xvpermi.q $xr1, $xr2, 2
-; LA64-NEXT: xvori.b $xr0, $xr1, 0
+; LA64-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
; LA64-NEXT: ret
%trunc = trunc <16 x i32> %arg to <16 x i16>
ret <16 x i16> %trunc
@@ -531,76 +243,28 @@ define <16 x i16> @test_trunc_v16i32_to_v16i16(<16 x i32> %arg) {
define <16 x i8> @test_trunc_v16i64_to_v16i8(<16 x i64> %arg) {
; LA32-LABEL: test_trunc_v16i64_to_v16i8:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 7
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 8
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 9
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 10
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 11
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 12
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 13
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 14
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
-; LA32-NEXT: vinsgr2vr.b $vr4, $a0, 15
-; LA32-NEXT: vori.b $vr0, $vr4, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA32-NEXT: xvpermi.d $xr1, $xr1, 216
+; LA32-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.b $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v16i64_to_v16i8:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 4
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 5
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 6
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 7
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 8
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 9
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 10
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 11
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 12
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 13
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 14
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
-; LA64-NEXT: vinsgr2vr.b $vr4, $a0, 15
-; LA64-NEXT: vori.b $vr0, $vr4, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA64-NEXT: xvpermi.d $xr1, $xr1, 216
+; LA64-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.b $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: # kill: def $vr0 killed $vr0 killed $xr0
; LA64-NEXT: ret
%trunc = trunc <16 x i64> %arg to <16 x i8>
ret <16 x i8> %trunc
@@ -609,78 +273,22 @@ define <16 x i8> @test_trunc_v16i64_to_v16i8(<16 x i64> %arg) {
define <16 x i16> @test_trunc_v16i64_to_v16i16(<16 x i64> %arg) {
; LA32-LABEL: test_trunc_v16i64_to_v16i16:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
-; LA32-NEXT: vinsgr2vr.h $vr4, $a0, 7
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA32-NEXT: xvpermi.q $xr2, $xr4, 2
-; LA32-NEXT: xvori.b $xr0, $xr2, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA32-NEXT: xvpermi.d $xr1, $xr1, 216
+; LA32-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v16i64_to_v16i16:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 4
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 5
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 6
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
-; LA64-NEXT: vinsgr2vr.h $vr4, $a0, 7
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; LA64-NEXT: xvpermi.q $xr2, $xr4, 2
-; LA64-NEXT: xvori.b $xr0, $xr2, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA64-NEXT: xvpermi.d $xr1, $xr1, 216
+; LA64-NEXT: xvpickev.h $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
; LA64-NEXT: ret
%trunc = trunc <16 x i64> %arg to <16 x i16>
ret <16 x i16> %trunc
@@ -689,80 +297,18 @@ define <16 x i16> @test_trunc_v16i64_to_v16i16(<16 x i64> %arg) {
define <16 x i32> @test_trunc_v16i64_to_v16i32(<16 x i64> %arg) {
; LA32-LABEL: test_trunc_v16i64_to_v16i32:
; LA32: # %bb.0:
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; LA32-NEXT: vinsgr2vr.w $vr5, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr4, $a0, 3
-; LA32-NEXT: xvpermi.q $xr4, $xr5, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 0
-; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 2
-; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 4
-; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr3, 6
-; LA32-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr2, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA32-NEXT: xvpermi.q $xr1, $xr0, 2
-; LA32-NEXT: xvori.b $xr0, $xr4, 0
+; LA32-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA32-NEXT: xvpermi.d $xr1, $xr1, 216
; LA32-NEXT: ret
;
; LA64-LABEL: test_trunc_v16i64_to_v16i32:
; LA64: # %bb.0:
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 0
-; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 1
-; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 2
-; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr1, 3
-; LA64-NEXT: vinsgr2vr.w $vr5, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.w $vr4, $a0, 3
-; LA64-NEXT: xvpermi.q $xr4, $xr5, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 0
-; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 1
-; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 2
-; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr3, 3
-; LA64-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 1
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 2
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr2, 3
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA64-NEXT: xvpermi.q $xr1, $xr0, 2
-; LA64-NEXT: xvori.b $xr0, $xr4, 0
+; LA64-NEXT: xvpickev.w $xr0, $xr1, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: xvpickev.w $xr1, $xr3, $xr2
+; LA64-NEXT: xvpermi.d $xr1, $xr1, 216
; LA64-NEXT: ret
%trunc = trunc <16 x i64> %arg to <16 x i32>
ret <16 x i32> %trunc
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vxi1-masks.ll b/llvm/test/CodeGen/LoongArch/lasx/vxi1-masks.ll
index cb28d79b0dd51..bd17e67d19fa3 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vxi1-masks.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vxi1-masks.ll
@@ -8,16 +8,10 @@ define void @xor_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 0
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 2
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 3
-; LA32-NEXT: vldi $vr0, -1777
-; LA32-NEXT: vxor.v $vr0, $vr1, $vr0
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vxor.v $vr0, $vr0, $vr1
; LA32-NEXT: vextrins.w $vr1, $vr0, 2
; LA32-NEXT: vextrins.w $vr1, $vr0, 35
; LA32-NEXT: vextrins.w $vr0, $vr0, 33
@@ -97,16 +91,10 @@ define void @xor_sext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 0
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 2
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 3
-; LA32-NEXT: vldi $vr0, -1777
-; LA32-NEXT: vxor.v $vr0, $vr1, $vr0
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vxor.v $vr0, $vr0, $vr1
; LA32-NEXT: vext2xv.d.w $xr0, $xr0
; LA32-NEXT: xvst $xr0, $a0, 0
; LA32-NEXT: ret
@@ -181,14 +169,13 @@ define void @or_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 6
-; LA32-NEXT: xvpickve2gr.w $a2, $xr0, 2
-; LA32-NEXT: vrepli.b $vr0, -1
-; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 1
-; LA32-NEXT: vinsgr2vr.w $vr0, $a1, 3
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vor.v $vr0, $vr0, $vr1
; LA32-NEXT: vextrins.w $vr1, $vr0, 2
+; LA32-NEXT: vextrins.w $vr1, $vr0, 35
; LA32-NEXT: vextrins.w $vr0, $vr0, 33
-; LA32-NEXT: vinsgr2vr.w $vr1, $a1, 2
; LA32-NEXT: xvpermi.q $xr0, $xr1, 2
; LA32-NEXT: xvrepli.d $xr1, 1
; LA32-NEXT: xvand.v $xr0, $xr0, $xr1
@@ -265,11 +252,10 @@ define void @or_sext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 6
-; LA32-NEXT: xvpickve2gr.w $a2, $xr0, 2
-; LA32-NEXT: vrepli.b $vr0, -1
-; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 1
-; LA32-NEXT: vinsgr2vr.w $vr0, $a1, 3
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vor.v $vr0, $vr0, $vr1
; LA32-NEXT: vext2xv.d.w $xr0, $xr0
; LA32-NEXT: xvst $xr0, $a0, 0
; LA32-NEXT: ret
@@ -341,10 +327,16 @@ define void @and_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvrepli.b $xr1, 0
-; LA32-NEXT: xvextrins.w $xr1, $xr0, 0
-; LA32-NEXT: xvrepli.d $xr0, 1
-; LA32-NEXT: xvand.v $xr0, $xr1, $xr0
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vand.v $vr0, $vr0, $vr1
+; LA32-NEXT: vextrins.w $vr1, $vr0, 2
+; LA32-NEXT: vextrins.w $vr1, $vr0, 35
+; LA32-NEXT: vextrins.w $vr0, $vr0, 33
+; LA32-NEXT: xvpermi.q $xr0, $xr1, 2
+; LA32-NEXT: xvrepli.d $xr1, 1
+; LA32-NEXT: xvand.v $xr0, $xr0, $xr1
; LA32-NEXT: xvst $xr0, $a0, 0
; LA32-NEXT: ret
;
@@ -412,11 +404,10 @@ define void @and_sext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
; LA32-NEXT: xvld $xr0, $a1, 0
; LA32-NEXT: xvld $xr1, $a2, 0
; LA32-NEXT: xvfcmp.clt.d $xr0, $xr0, $xr1
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 4
-; LA32-NEXT: xvpickve2gr.w $a2, $xr0, 0
-; LA32-NEXT: vrepli.b $vr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr0, $a2, 0
-; LA32-NEXT: vinsgr2vr.w $vr0, $a1, 2
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vldi $vr1, -1777
+; LA32-NEXT: vand.v $vr0, $vr0, $vr1
; LA32-NEXT: vext2xv.d.w $xr0, $xr0
; LA32-NEXT: xvst $xr0, $a0, 0
; LA32-NEXT: ret
diff --git a/llvm/test/CodeGen/LoongArch/lasx/xvmskcond.ll b/llvm/test/CodeGen/LoongArch/lasx/xvmskcond.ll
index ca61e69f1b378..bb8cc2abbec35 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/xvmskcond.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/xvmskcond.ll
@@ -883,39 +883,24 @@ define i8 @xvmsk_ne_v4i32_concat_poison(<4 x i32> %vec) {
}
define i8 @xvmsk_ogt_v4f64_concat_poison(<4 x double> %vec) {
-; LA32-LABEL: xvmsk_ogt_v4f64_concat_poison:
-; LA32: # %bb.0:
-; LA32-NEXT: xvrepli.b $xr1, 0
-; LA32-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: xvpickve2gr.w $a1, $xr0, 4
-; LA32-NEXT: xvpickve2gr.w $a2, $xr0, 2
-; LA32-NEXT: xvpickve2gr.w $a3, $xr0, 0
-; LA32-NEXT: vinsgr2vr.h $vr0, $a3, 0
-; LA32-NEXT: vinsgr2vr.h $vr0, $a2, 1
-; LA32-NEXT: vinsgr2vr.h $vr0, $a1, 2
-; LA32-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; LA32-NEXT: vslli.h $vr0, $vr0, 15
-; LA32-NEXT: vmskltz.h $vr0, $vr0
-; LA32-NEXT: vpickve2gr.hu $a0, $vr0, 0
-; LA32-NEXT: ret
-;
-; LA64-LABEL: xvmsk_ogt_v4f64_concat_poison:
-; LA64: # %bb.0:
-; LA64-NEXT: xvrepli.b $xr1, 0
-; LA64-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: xvpickve2gr.d $a1, $xr0, 2
-; LA64-NEXT: xvpickve2gr.d $a2, $xr0, 1
-; LA64-NEXT: xvpickve2gr.d $a3, $xr0, 0
-; LA64-NEXT: vinsgr2vr.h $vr0, $a3, 0
-; LA64-NEXT: vinsgr2vr.h $vr0, $a2, 1
-; LA64-NEXT: vinsgr2vr.h $vr0, $a1, 2
-; LA64-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; LA64-NEXT: vslli.h $vr0, $vr0, 15
-; LA64-NEXT: vmskltz.h $vr0, $vr0
-; LA64-NEXT: vpickve2gr.hu $a0, $vr0, 0
-; LA64-NEXT: ret
+; CHECK-LABEL: xvmsk_ogt_v4f64_concat_poison:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xvrepli.b $xr1, 0
+; CHECK-NEXT: xvfcmp.clt.d $xr0, $xr1, $xr0
+; CHECK-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; CHECK-NEXT: xvpermi.d $xr0, $xr0, 216
+; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 0
+; CHECK-NEXT: vinsgr2vr.h $vr1, $a0, 0
+; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 1
+; CHECK-NEXT: vinsgr2vr.h $vr1, $a0, 1
+; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 2
+; CHECK-NEXT: vinsgr2vr.h $vr1, $a0, 2
+; CHECK-NEXT: vpickve2gr.w $a0, $vr0, 3
+; CHECK-NEXT: vinsgr2vr.h $vr1, $a0, 3
+; CHECK-NEXT: vslli.h $vr0, $vr1, 15
+; CHECK-NEXT: vmskltz.h $vr0, $vr0
+; CHECK-NEXT: vpickve2gr.hu $a0, $vr0, 0
+; CHECK-NEXT: ret
%tobool = fcmp ogt <4 x double> %vec, zeroinitializer
%insertvec = shufflevector <4 x i1> %tobool, <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
%res = bitcast <8 x i1> %insertvec to i8
diff --git a/llvm/test/CodeGen/LoongArch/pr177863.ll b/llvm/test/CodeGen/LoongArch/pr177863.ll
index 54fa02162ee0d..c8fbba8500fc2 100644
--- a/llvm/test/CodeGen/LoongArch/pr177863.ll
+++ b/llvm/test/CodeGen/LoongArch/pr177863.ll
@@ -7,29 +7,17 @@ define <4 x i1> @test(<4 x i64> %shuffle2, <4 x i64> %shuffle4) {
; LA32-LABEL: test:
; LA32: # %bb.0: # %entry
; LA32-NEXT: xvseq.d $xr0, $xr1, $xr0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 0
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 2
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 4
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA32-NEXT: xvpickve2gr.w $a0, $xr0, 6
-; LA32-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA32-NEXT: vxori.b $vr0, $vr1, 255
+; LA32-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA32-NEXT: vxori.b $vr0, $vr0, 255
; LA32-NEXT: ret
;
; LA64-LABEL: test:
; LA64: # %bb.0: # %entry
; LA64-NEXT: xvseq.d $xr0, $xr1, $xr0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 0
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 0
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 1
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 1
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 2
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 2
-; LA64-NEXT: xvpickve2gr.d $a0, $xr0, 3
-; LA64-NEXT: vinsgr2vr.w $vr1, $a0, 3
-; LA64-NEXT: vxori.b $vr0, $vr1, 255
+; LA64-NEXT: xvpickev.w $xr0, $xr0, $xr0
+; LA64-NEXT: xvpermi.d $xr0, $xr0, 216
+; LA64-NEXT: vxori.b $vr0, $vr0, 255
; LA64-NEXT: ret
entry:
%conv5 = trunc nuw <4 x i64> %shuffle4 to <4 x i32>
More information about the llvm-commits
mailing list