Skip to content

Commit 4ac55f1

Browse files
author
zhangtiehu
committed
[X86] Lower mathlib call ldexp into scalef when avx512 is enabled
1 parent e34c35a commit 4ac55f1

File tree

3 files changed

+535
-111
lines changed

3 files changed

+535
-111
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,15 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
24052405
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i128, Custom);
24062406
}
24072407

2408+
if (Subtarget.hasAVX512()) {
2409+
for (MVT VT : { MVT::f16, MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64 })
2410+
setOperationAction(ISD::FLDEXP, VT, Custom);
2411+
2412+
if (Subtarget.hasVLX())
2413+
for (MVT VT : { MVT::v8f32, MVT::v4f64, MVT::v16f32, MVT::v8f64 })
2414+
setOperationAction(ISD::FLDEXP, VT, Custom);
2415+
}
2416+
24082417
// On 32 bit MSVC, `fmodf(f32)` is not defined - only `fmod(f64)`
24092418
// is. We should promote the value to 64-bits to solve this.
24102419
// This is what the CRT headers do - `fmodf` is an inline header
@@ -31814,6 +31823,57 @@ static StringRef getInstrStrFromOpNo(const SmallVectorImpl<StringRef> &AsmStrs,
3181431823
return StringRef();
3181531824
}
3181631825

31826+
static SDValue LowerFLDEXP(SDValue Op, const X86Subtarget &Subtarget,
31827+
SelectionDAG &DAG) {
31828+
SDValue X = Op.getOperand(0);
31829+
EVT XTy = X.getValueType();
31830+
SDValue Exp = Op.getOperand(1);
31831+
SDLoc DL(Op);
31832+
EVT XVT, ExpVT;
31833+
switch (Op.getSimpleValueType().SimpleTy) {
31834+
default:
31835+
return SDValue();
31836+
case MVT::f16:
31837+
// TODO: Choose vscalefph when fp16 for ISD::FLDEXP is fully supported.
31838+
X = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, X);
31839+
[[fallthrough]];
31840+
case MVT::f32:
31841+
XVT = MVT::v4f32;
31842+
ExpVT = MVT::v4f32;
31843+
break;
31844+
case MVT::f64:
31845+
XVT = MVT::v2f64;
31846+
ExpVT = MVT::v2f64;
31847+
break;
31848+
case MVT::v4f32:
31849+
case MVT::v2f64:
31850+
if (!Subtarget.hasVLX()) {
31851+
Exp = DAG.getNode(ISD::SINT_TO_FP, DL, XTy, Exp);
31852+
return DAG.getNode(X86ISD::SCALEFS, DL, XTy, X, Exp, X);
31853+
}
31854+
case MVT::v8f32:
31855+
case MVT::v4f64:
31856+
case MVT::v16f32:
31857+
case MVT::v8f64:
31858+
Exp = DAG.getNode(ISD::SINT_TO_FP, DL, XTy, Exp);
31859+
return DAG.getNode(X86ISD::SCALEF, DL, XTy, X, Exp, X);
31860+
}
31861+
31862+
SDValue Zero = DAG.getConstant(0, DL, MVT::i64);
31863+
Exp = DAG.getNode(ISD::SINT_TO_FP, DL, X.getValueType(), Exp);
31864+
SDValue VX =
31865+
DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, XVT, DAG.getUNDEF(XVT), X, Zero);
31866+
SDValue VExp = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ExpVT,
31867+
DAG.getUNDEF(ExpVT), Exp, Zero);
31868+
SDValue Scalef = DAG.getNode(X86ISD::SCALEFS, DL, XVT, VX, VExp, VX);
31869+
SDValue Final =
31870+
DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, X.getValueType(), Scalef, Zero);
31871+
if (X.getValueType() != XTy)
31872+
Final = DAG.getNode(ISD::FP_ROUND, DL, XTy, Final,
31873+
DAG.getIntPtrConstant(1, SDLoc(Op)));
31874+
return Final;
31875+
}
31876+
3181731877
bool X86TargetLowering::isInlineAsmTargetBranch(
3181831878
const SmallVectorImpl<StringRef> &AsmStrs, unsigned OpNo) const {
3181931879
// In a __asm block, __asm inst foo where inst is CALL or JMP should be
@@ -31979,6 +32039,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
3197932039
case ISD::ADDRSPACECAST: return LowerADDRSPACECAST(Op, DAG);
3198032040
case X86ISD::CVTPS2PH: return LowerCVTPS2PH(Op, DAG);
3198132041
case ISD::PREFETCH: return LowerPREFETCH(Op, Subtarget, DAG);
32042+
case ISD::FLDEXP: return LowerFLDEXP(Op, Subtarget, DAG);
3198232043
}
3198332044
}
3198432045

0 commit comments

Comments
 (0)