Skip to content

[LoongArch] Load floating-point immediate using VLDI #101923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5573,14 +5573,32 @@ SDValue LoongArchTargetLowering::LowerReturn(
return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps);
}

bool LoongArchTargetLowering::isFPImmVLDILegal(const APFloat &Imm,
EVT VT) const {
if (!Subtarget.hasExtLSX())
return false;

if (VT == MVT::f32) {
uint64_t masked = Imm.bitcastToAPInt().getZExtValue() & 0x7e07ffff;
return (masked == 0x3e000000 || masked == 0x40000000);
}

if (VT == MVT::f64) {
uint64_t masked = Imm.bitcastToAPInt().getZExtValue() & 0x7fc0ffffffffffff;
return (masked == 0x3fc0000000000000 || masked == 0x4000000000000000);
}

return false;
}

bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
// TODO: Maybe need more checks here after vector extension is supported.
if (VT == MVT::f32 && !Subtarget.hasBasicF())
return false;
if (VT == MVT::f64 && !Subtarget.hasBasicD())
return false;
return (Imm.isZero() || Imm.isExactlyValue(+1.0));
return (Imm.isZero() || Imm.isExactlyValue(1.0) || isFPImmVLDILegal(Imm, VT));
}

bool LoongArchTargetLowering::isCheapToSpeculateCttz(Type *) const {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ class LoongArchTargetLowering : public TargetLowering {
bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,
Align &PrefAlign) const override;

bool isFPImmVLDILegal(const APFloat &Imm, EVT VT) const;

private:
/// Target-specific function used to lower LoongArch calling conventions.
typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,
Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,29 @@ def to_valid_timm : SDNodeXForm<timm, [{
return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT());
}]>;

// FP immediate of VLDI patterns.
def f32imm_vldi : PatLeaf<(fpimm), [{
const auto &TLI =
*static_cast<const LoongArchTargetLowering*>(getTargetLowering());
return TLI.isFPImmVLDILegal(N->getValueAPF(), MVT::f32);
}]>;
def f64imm_vldi : PatLeaf<(fpimm), [{
const auto &TLI =
*static_cast<const LoongArchTargetLowering*>(getTargetLowering());
return TLI.isFPImmVLDILegal(N->getValueAPF(), MVT::f64);
}]>;

def to_f32imm_vldi : SDNodeXForm<fpimm, [{
uint64_t x = N->getValueAPF().bitcastToAPInt().getZExtValue();
x = (0b11011 << 8) | (((x >> 24) & 0xc0) ^ 0x40) | ((x >> 19) & 0x3f);
return CurDAG->getTargetConstant(SignExtend32<13>(x), SDLoc(N), MVT::i32);
}]>;
def to_f64imm_vldi : SDNodeXForm<fpimm, [{
uint64_t x = N->getValueAPF().bitcastToAPInt().getZExtValue();
x = (0b11100 << 8) | (((x >> 56) & 0xc0) ^ 0x40) | ((x >> 48) & 0x3f);
return CurDAG->getTargetConstant(SignExtend32<13>(x), SDLoc(N), MVT::i32);
}]>;

//===----------------------------------------------------------------------===//
// Instruction class templates
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -663,7 +686,9 @@ def VMSKGEZ_B : LSX2R_VV<0x729c5000>;

def VMSKNZ_B : LSX2R_VV<0x729c6000>;

let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def VLDI : LSX1RI13_VI<0x73e00000>;
}

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

// Vector loads floating-point constants
def : Pat<(f32 f32imm_vldi:$in),
(f32 (EXTRACT_SUBREG (VLDI (to_f32imm_vldi f32imm_vldi:$in)), sub_32))>;
def : Pat<(f64 f64imm_vldi:$in),
(f64 (EXTRACT_SUBREG (VLDI (to_f64imm_vldi f64imm_vldi:$in)), sub_64))>;

} // Predicates = [HasExtLSX]

/// Intrinsic pattern
Expand Down
Loading
Loading