Skip to content

Commit dbae30d

Browse files
authored
[LoongArch] Load floating-point immediate using VLDI (#101923)
This commit uses the VLDI instruction to load some common floating-point constants when the LSX feature is enabled.
1 parent e1a16cd commit dbae30d

File tree

4 files changed

+1334
-3845
lines changed

4 files changed

+1334
-3845
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5573,14 +5573,32 @@ SDValue LoongArchTargetLowering::LowerReturn(
55735573
return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps);
55745574
}
55755575

5576+
bool LoongArchTargetLowering::isFPImmVLDILegal(const APFloat &Imm,
5577+
EVT VT) const {
5578+
if (!Subtarget.hasExtLSX())
5579+
return false;
5580+
5581+
if (VT == MVT::f32) {
5582+
uint64_t masked = Imm.bitcastToAPInt().getZExtValue() & 0x7e07ffff;
5583+
return (masked == 0x3e000000 || masked == 0x40000000);
5584+
}
5585+
5586+
if (VT == MVT::f64) {
5587+
uint64_t masked = Imm.bitcastToAPInt().getZExtValue() & 0x7fc0ffffffffffff;
5588+
return (masked == 0x3fc0000000000000 || masked == 0x4000000000000000);
5589+
}
5590+
5591+
return false;
5592+
}
5593+
55765594
bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
55775595
bool ForCodeSize) const {
55785596
// TODO: Maybe need more checks here after vector extension is supported.
55795597
if (VT == MVT::f32 && !Subtarget.hasBasicF())
55805598
return false;
55815599
if (VT == MVT::f64 && !Subtarget.hasBasicD())
55825600
return false;
5583-
return (Imm.isZero() || Imm.isExactlyValue(+1.0));
5601+
return (Imm.isZero() || Imm.isExactlyValue(1.0) || isFPImmVLDILegal(Imm, VT));
55845602
}
55855603

55865604
bool LoongArchTargetLowering::isCheapToSpeculateCttz(Type *) const {

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ class LoongArchTargetLowering : public TargetLowering {
260260
bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,
261261
Align &PrefAlign) const override;
262262

263+
bool isFPImmVLDILegal(const APFloat &Imm, EVT VT) const;
264+
263265
private:
264266
/// Target-specific function used to lower LoongArch calling conventions.
265267
typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,

llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,29 @@ def to_valid_timm : SDNodeXForm<timm, [{
203203
return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT());
204204
}]>;
205205

206+
// FP immediate of VLDI patterns.
207+
def f32imm_vldi : PatLeaf<(fpimm), [{
208+
const auto &TLI =
209+
*static_cast<const LoongArchTargetLowering*>(getTargetLowering());
210+
return TLI.isFPImmVLDILegal(N->getValueAPF(), MVT::f32);
211+
}]>;
212+
def f64imm_vldi : PatLeaf<(fpimm), [{
213+
const auto &TLI =
214+
*static_cast<const LoongArchTargetLowering*>(getTargetLowering());
215+
return TLI.isFPImmVLDILegal(N->getValueAPF(), MVT::f64);
216+
}]>;
217+
218+
def to_f32imm_vldi : SDNodeXForm<fpimm, [{
219+
uint64_t x = N->getValueAPF().bitcastToAPInt().getZExtValue();
220+
x = (0b11011 << 8) | (((x >> 24) & 0xc0) ^ 0x40) | ((x >> 19) & 0x3f);
221+
return CurDAG->getTargetConstant(SignExtend32<13>(x), SDLoc(N), MVT::i32);
222+
}]>;
223+
def to_f64imm_vldi : SDNodeXForm<fpimm, [{
224+
uint64_t x = N->getValueAPF().bitcastToAPInt().getZExtValue();
225+
x = (0b11100 << 8) | (((x >> 56) & 0xc0) ^ 0x40) | ((x >> 48) & 0x3f);
226+
return CurDAG->getTargetConstant(SignExtend32<13>(x), SDLoc(N), MVT::i32);
227+
}]>;
228+
206229
//===----------------------------------------------------------------------===//
207230
// Instruction class templates
208231
//===----------------------------------------------------------------------===//
@@ -663,7 +686,9 @@ def VMSKGEZ_B : LSX2R_VV<0x729c5000>;
663686

664687
def VMSKNZ_B : LSX2R_VV<0x729c6000>;
665688

689+
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
666690
def VLDI : LSX1RI13_VI<0x73e00000>;
691+
}
667692

668693
def VAND_V : LSX3R_VVV<0x71260000>;
669694
def VOR_V : LSX3R_VVV<0x71268000>;
@@ -1910,6 +1935,12 @@ def : Pat<(v2i64 (fp_to_sint v2f64:$vj)), (VFTINTRZ_L_D v2f64:$vj)>;
19101935
def : Pat<(v4i32 (fp_to_uint v4f32:$vj)), (VFTINTRZ_WU_S v4f32:$vj)>;
19111936
def : Pat<(v2i64 (fp_to_uint v2f64:$vj)), (VFTINTRZ_LU_D v2f64:$vj)>;
19121937

1938+
// Vector loads floating-point constants
1939+
def : Pat<(f32 f32imm_vldi:$in),
1940+
(f32 (EXTRACT_SUBREG (VLDI (to_f32imm_vldi f32imm_vldi:$in)), sub_32))>;
1941+
def : Pat<(f64 f64imm_vldi:$in),
1942+
(f64 (EXTRACT_SUBREG (VLDI (to_f64imm_vldi f64imm_vldi:$in)), sub_64))>;
1943+
19131944
} // Predicates = [HasExtLSX]
19141945

19151946
/// Intrinsic pattern

0 commit comments

Comments
 (0)