[llvm] [LoongArch] Type legalize v2f32 loads by using an f64 load and a scalar_to_vector (PR #164943)
Zhaoxin Yang via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 24 01:50:41 PDT 2025
https://github.com/ylzsx created https://github.com/llvm/llvm-project/pull/164943
On 64-bit targets the generic legalize will use an i64 load and a scalar_to_vector for us. But on 32-bit targets, i64 isn't legal, and the generic legalizer will end up emitting two 32-bit loads. This patch uses f64 to avoid the splitting entirely and the redundant int->fp conversion.
>From 4ad1cb474dddd0b2ba0fedb6a6eab8d2d87c443a Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Fri, 24 Oct 2025 16:43:10 +0800
Subject: [PATCH] [LoongArch] Type legalize v2f32 loads by using an f64 load
and a scalar_to_vector.
On 64-bit targets the generic legalize will use an i64 load and a
scalar_to_vector for us. But on 32-bit targets i64 isn't legal and the
generic legalizer will end up emitting two 32-bit loads.
---
.../LoongArch/LoongArchISelLowering.cpp | 28 +++++++++++++++++++
llvm/test/CodeGen/LoongArch/vector-fp-imm.ll | 3 +-
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index ca4a655f06587..442a6d23795ad 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -386,6 +386,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
}
+ // We want to legalize this to an f64 load rather than an i64 load.
+ setOperationAction(ISD::LOAD, MVT::v2f32, Custom);
}
// Set operations for 'LASX' feature.
@@ -4668,6 +4670,32 @@ void LoongArchTargetLowering::ReplaceNodeResults(
"Unexpected custom legalisation");
Results.push_back(customLegalizeToWOp(N, DAG, 2));
break;
+ case ISD::LOAD: {
+ // Use an f64 load and a scalar_to_vector for v2f32 loads. This avoids
+ // scalarizing in 32-bit mode. In 64-bit mode this avoids a int->fp
+ // cast since type legalization will try to use an i64 load.
+ MVT VT = N->getSimpleValueType(0);
+ assert(VT == MVT::v2f32 && "Unexpected VT");
+ assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
+ "Unexpected type action!");
+ if (!ISD::isNON_EXTLoad(N))
+ return;
+ auto *Ld = cast<LoadSDNode>(N);
+ if (Subtarget.hasExtLSX()) {
+ MVT LdVT = MVT::f64;
+ SDValue Res = DAG.getLoad(LdVT, DL, Ld->getChain(), Ld->getBasePtr(),
+ Ld->getPointerInfo(), Ld->getBaseAlign(),
+ Ld->getMemOperand()->getFlags());
+ SDValue Chain = Res.getValue(1);
+ MVT VecVT = MVT::getVectorVT(LdVT, 2);
+ Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, Res);
+ EVT WideVT = getTypeToTransformTo(*DAG.getContext(), VT);
+ Res = DAG.getBitcast(WideVT, Res);
+ Results.push_back(Res);
+ Results.push_back(Chain);
+ }
+ break;
+ }
case ISD::FP_TO_SINT: {
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
"Unexpected custom legalisation");
diff --git a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
index 16c9e754fb94d..48dd0b9e03bca 100644
--- a/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
+++ b/llvm/test/CodeGen/LoongArch/vector-fp-imm.ll
@@ -123,8 +123,7 @@ define void @test_f2(ptr %P, ptr %S) nounwind {
;
; LA64D-LABEL: test_f2:
; LA64D: # %bb.0:
-; LA64D-NEXT: ld.d $a0, $a0, 0
-; LA64D-NEXT: vinsgr2vr.d $vr0, $a0, 0
+; LA64D-NEXT: fld.d $fa0, $a0, 0
; LA64D-NEXT: lu12i.w $a0, 260096
; LA64D-NEXT: lu52i.d $a0, $a0, 1024
; LA64D-NEXT: vreplgr2vr.d $vr1, $a0
More information about the llvm-commits
mailing list