[llvm] [LoongArch] Specially legalizing for several 128-bit vector trunc cases (PR #170403)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 2 18:28:33 PST 2025


https://github.com/zhaoqi5 created https://github.com/llvm/llvm-project/pull/170403

None

>From 7f90183c7218f30ba5e9844625b0f889bd28d280 Mon Sep 17 00:00:00 2001
From: Qi Zhao <zhaoqi01 at loongson.cn>
Date: Wed, 3 Dec 2025 10:25:14 +0800
Subject: [PATCH] [LoongArch] Specially legalizing for several 128-bit vector
 trunc cases

---
 .../LoongArch/LoongArchISelLowering.cpp       | 14 ++++++-
 llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll  | 39 ++++++++-----------
 2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index ba9d0682b26dd..7e0ff1fdc626f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -5158,8 +5158,20 @@ void LoongArchTargetLowering::ReplaceNodeResults(
         assert(isTypeLegal(WidenVT) && isTypeLegal(WidenIn.getValueType()) &&
                "Illegal vector type in truncation");
         WidenIn = DAG.getBitcast(WidenVT, WidenIn);
+
+        SDValue ResIn = WidenIn;
+        if (MinElts == 2 && Scale != 2) {
+          SmallVector<int, 4> Mask = {-1, -1, -1, -1};
+          Mask[0] = InVT == MVT::v2i32 ? 1 : 2;
+          SDValue CastIn = DAG.getBitcast(MVT::v4i32, WidenIn);
+          SDValue ExtractIn =
+              DAG.getVectorShuffle(MVT::v4i32, DL, CastIn, CastIn, Mask);
+          ResIn = DAG.getBitcast(WidenVT, ExtractIn);
+          TruncMask[1] = WidenVT.getVectorNumElements();
+        }
+
         Results.push_back(
-            DAG.getVectorShuffle(WidenVT, DL, WidenIn, WidenIn, TruncMask));
+            DAG.getVectorShuffle(WidenVT, DL, WidenIn, ResIn, TruncMask));
         return;
       }
     }
diff --git a/llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll b/llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll
index 314350acd23d6..d1050b5d5ca82 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/vec-trunc.ll
@@ -28,20 +28,18 @@ define void @load_trunc_2i64_to_2i16(ptr %ptr, ptr %dst) nounwind {
 ; LA32-LABEL: load_trunc_2i64_to_2i16:
 ; LA32:       # %bb.0:
 ; LA32-NEXT:    vld $vr0, $a0, 0
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI1_0)
-; LA32-NEXT:    vld $vr1, $a0, %pc_lo12(.LCPI1_0)
-; LA32-NEXT:    vshuf.h $vr1, $vr0, $vr0
-; LA32-NEXT:    vpickve2gr.w $a0, $vr1, 0
+; LA32-NEXT:    vreplvei.w $vr1, $vr0, 2
+; LA32-NEXT:    vpackev.h $vr0, $vr1, $vr0
+; LA32-NEXT:    vpickve2gr.w $a0, $vr0, 0
 ; LA32-NEXT:    st.w $a0, $a1, 0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_trunc_2i64_to_2i16:
 ; LA64:       # %bb.0:
 ; LA64-NEXT:    vld $vr0, $a0, 0
-; LA64-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI1_0)
-; LA64-NEXT:    vld $vr1, $a0, %pc_lo12(.LCPI1_0)
-; LA64-NEXT:    vshuf.h $vr1, $vr0, $vr0
-; LA64-NEXT:    vstelm.w $vr1, $a1, 0, 0
+; LA64-NEXT:    vreplvei.w $vr1, $vr0, 2
+; LA64-NEXT:    vpackev.h $vr0, $vr1, $vr0
+; LA64-NEXT:    vstelm.w $vr0, $a1, 0, 0
 ; LA64-NEXT:    ret
   %a = load <2 x i64>, ptr %ptr
   %trunc = trunc <2 x i64> %a to <2 x i16>
@@ -53,18 +51,16 @@ define void @load_trunc_2i64_to_2i8(ptr %ptr, ptr %dst) nounwind {
 ; LA32-LABEL: load_trunc_2i64_to_2i8:
 ; LA32:       # %bb.0:
 ; LA32-NEXT:    vld $vr0, $a0, 0
-; LA32-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA32-NEXT:    vld $vr1, $a0, %pc_lo12(.LCPI2_0)
-; LA32-NEXT:    vshuf.b $vr0, $vr0, $vr0, $vr1
+; LA32-NEXT:    vreplvei.w $vr1, $vr0, 2
+; LA32-NEXT:    vpackev.b $vr0, $vr1, $vr0
 ; LA32-NEXT:    vstelm.h $vr0, $a1, 0, 0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_trunc_2i64_to_2i8:
 ; LA64:       # %bb.0:
 ; LA64-NEXT:    vld $vr0, $a0, 0
-; LA64-NEXT:    pcalau12i $a0, %pc_hi20(.LCPI2_0)
-; LA64-NEXT:    vld $vr1, $a0, %pc_lo12(.LCPI2_0)
-; LA64-NEXT:    vshuf.b $vr0, $vr0, $vr0, $vr1
+; LA64-NEXT:    vreplvei.w $vr1, $vr0, 2
+; LA64-NEXT:    vpackev.b $vr0, $vr1, $vr0
 ; LA64-NEXT:    vstelm.h $vr0, $a1, 0, 0
 ; LA64-NEXT:    ret
   %a = load <2 x i64>, ptr %ptr
@@ -174,21 +170,18 @@ define void @load_trunc_2i32_to_2i8(ptr %ptr, ptr %dst) nounwind {
 ; LA32:       # %bb.0:
 ; LA32-NEXT:    ld.w $a2, $a0, 0
 ; LA32-NEXT:    ld.w $a0, $a0, 4
-; LA32-NEXT:    pcalau12i $a3, %pc_hi20(.LCPI7_0)
-; LA32-NEXT:    vld $vr0, $a3, %pc_lo12(.LCPI7_0)
-; LA32-NEXT:    vinsgr2vr.w $vr1, $a2, 0
-; LA32-NEXT:    vinsgr2vr.w $vr1, $a0, 1
-; LA32-NEXT:    vshuf.b $vr0, $vr0, $vr1, $vr0
+; LA32-NEXT:    vinsgr2vr.w $vr0, $a2, 0
+; LA32-NEXT:    vreplgr2vr.w $vr1, $a0
+; LA32-NEXT:    vpackev.b $vr0, $vr1, $vr0
 ; LA32-NEXT:    vstelm.h $vr0, $a1, 0, 0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: load_trunc_2i32_to_2i8:
 ; LA64:       # %bb.0:
 ; LA64-NEXT:    ld.d $a0, $a0, 0
-; LA64-NEXT:    pcalau12i $a2, %pc_hi20(.LCPI7_0)
-; LA64-NEXT:    vld $vr0, $a2, %pc_lo12(.LCPI7_0)
-; LA64-NEXT:    vinsgr2vr.d $vr1, $a0, 0
-; LA64-NEXT:    vshuf.b $vr0, $vr0, $vr1, $vr0
+; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0
+; LA64-NEXT:    vreplvei.w $vr1, $vr0, 1
+; LA64-NEXT:    vpackev.b $vr0, $vr1, $vr0
 ; LA64-NEXT:    vstelm.h $vr0, $a1, 0, 0
 ; LA64-NEXT:    ret
   %a = load <2 x i32>, ptr %ptr



More information about the llvm-commits mailing list