mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC] Pass nofpexcept flag to custom lowered constrained ops
This is a follow-up of D86605. For strict DAG FP node, if its FP exception behavior metadata is ignore, it should have nofpexcept flag. But during custom lowering, this flag isn't passed down. This is also seen on X86 target. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D87390
This commit is contained in:
parent
4dabbec93d
commit
d6e49b7d70
@ -1620,6 +1620,10 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
|
||||
SDLoc dl(N);
|
||||
SDValue Chain = Strict ? N->getOperand(0) : DAG.getEntryNode();
|
||||
|
||||
// TODO: Any other flags to propagate?
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoFPExcept(N->getFlags().hasNoFPExcept());
|
||||
|
||||
// First do an SINT_TO_FP, whether the original was signed or unsigned.
|
||||
// When promoting partial word types to i32 we must honor the signedness,
|
||||
// though.
|
||||
@ -1630,8 +1634,8 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
|
||||
Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
|
||||
APInt(NVT.getSizeInBits(), 0)), dl, NVT);
|
||||
if (Strict) {
|
||||
Hi = DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {NVT, MVT::Other},
|
||||
{Chain, Src});
|
||||
Hi = DAG.getNode(ISD::STRICT_SINT_TO_FP, dl,
|
||||
DAG.getVTList(NVT, MVT::Other), {Chain, Src}, Flags);
|
||||
Chain = Hi.getValue(1);
|
||||
} else
|
||||
Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
|
||||
@ -1690,12 +1694,12 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Are there fast-math-flags to propagate to this FADD?
|
||||
// TODO: Are there other fast-math-flags to propagate to this FADD?
|
||||
SDValue NewLo = DAG.getConstantFP(
|
||||
APFloat(APFloat::PPCDoubleDouble(), APInt(128, Parts)), dl, MVT::ppcf128);
|
||||
if (Strict) {
|
||||
Lo = DAG.getNode(ISD::STRICT_FADD, dl, {VT, MVT::Other},
|
||||
{Chain, Hi, NewLo});
|
||||
Lo = DAG.getNode(ISD::STRICT_FADD, dl, DAG.getVTList(VT, MVT::Other),
|
||||
{Chain, Hi, NewLo}, Flags);
|
||||
Chain = Lo.getValue(1);
|
||||
ReplaceValueWith(SDValue(N, 1), Chain);
|
||||
} else
|
||||
|
@ -8090,14 +8090,20 @@ static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
|
||||
bool IsStrict = Op->isStrictFPOpcode();
|
||||
bool IsSigned = Op.getOpcode() == ISD::FP_TO_SINT ||
|
||||
Op.getOpcode() == ISD::STRICT_FP_TO_SINT;
|
||||
|
||||
// TODO: Any other flags to propagate?
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
|
||||
|
||||
// For strict nodes, source is the second operand.
|
||||
SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
|
||||
SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
|
||||
assert(Src.getValueType().isFloatingPoint());
|
||||
if (Src.getValueType() == MVT::f32) {
|
||||
if (IsStrict) {
|
||||
Src = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {MVT::f64, MVT::Other},
|
||||
{Chain, Src});
|
||||
Src =
|
||||
DAG.getNode(ISD::STRICT_FP_EXTEND, dl,
|
||||
DAG.getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
|
||||
Chain = Src.getValue(1);
|
||||
} else
|
||||
Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
|
||||
@ -8117,7 +8123,8 @@ static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG,
|
||||
}
|
||||
if (IsStrict) {
|
||||
Opc = getPPCStrictOpcode(Opc);
|
||||
Conv = DAG.getNode(Opc, dl, {MVT::f64, MVT::Other}, {Chain, Src});
|
||||
Conv = DAG.getNode(Opc, dl, DAG.getVTList(MVT::f64, MVT::Other),
|
||||
{Chain, Src}, Flags);
|
||||
} else {
|
||||
Conv = DAG.getNode(Opc, dl, MVT::f64, Src);
|
||||
}
|
||||
@ -8398,6 +8405,11 @@ static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
|
||||
bool IsSigned = Op.getOpcode() == ISD::SINT_TO_FP ||
|
||||
Op.getOpcode() == ISD::STRICT_SINT_TO_FP;
|
||||
SDLoc dl(Op);
|
||||
|
||||
// TODO: Any other flags to propagate?
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
|
||||
|
||||
// If we have FCFIDS, then use it when converting to single-precision.
|
||||
// Otherwise, convert to double-precision and then round.
|
||||
bool IsSingle = Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
|
||||
@ -8407,8 +8419,8 @@ static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG,
|
||||
if (Op->isStrictFPOpcode()) {
|
||||
if (!Chain)
|
||||
Chain = Op.getOperand(0);
|
||||
return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl, {ConvTy, MVT::Other},
|
||||
{Chain, Src});
|
||||
return DAG.getNode(getPPCStrictOpcode(ConvOpc), dl,
|
||||
DAG.getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
|
||||
} else
|
||||
return DAG.getNode(ConvOpc, dl, ConvTy, Src);
|
||||
}
|
||||
@ -8464,6 +8476,10 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
|
||||
assert((Op.getValueType() == MVT::v2f64 || Op.getValueType() == MVT::v4f32) &&
|
||||
"Supports conversions to v2f64/v4f32 only.");
|
||||
|
||||
// TODO: Any other flags to propagate?
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
|
||||
|
||||
bool SignedConv = Opc == ISD::SINT_TO_FP || Opc == ISD::STRICT_SINT_TO_FP;
|
||||
bool FourEltRes = Op.getValueType() == MVT::v4f32;
|
||||
|
||||
@ -8503,8 +8519,8 @@ SDValue PPCTargetLowering::LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
|
||||
Extend = DAG.getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
|
||||
|
||||
if (IsStrict)
|
||||
return DAG.getNode(Opc, dl, {Op.getValueType(), MVT::Other},
|
||||
{Op.getOperand(0), Extend});
|
||||
return DAG.getNode(Opc, dl, DAG.getVTList(Op.getValueType(), MVT::Other),
|
||||
{Op.getOperand(0), Extend}, Flags);
|
||||
|
||||
return DAG.getNode(Opc, dl, Op.getValueType(), Extend);
|
||||
}
|
||||
@ -8518,6 +8534,10 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
|
||||
SDValue Src = Op.getOperand(IsStrict ? 1 : 0);
|
||||
SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
|
||||
|
||||
// TODO: Any other flags to propagate?
|
||||
SDNodeFlags Flags;
|
||||
Flags.setNoFPExcept(Op->getFlags().hasNoFPExcept());
|
||||
|
||||
EVT InVT = Src.getValueType();
|
||||
EVT OutVT = Op.getValueType();
|
||||
if (OutVT.isVector() && OutVT.isFloatingPoint() &&
|
||||
@ -8667,8 +8687,9 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
|
||||
|
||||
if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
|
||||
if (IsStrict)
|
||||
FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {MVT::f32, MVT::Other},
|
||||
{Chain, FP, DAG.getIntPtrConstant(0, dl)});
|
||||
FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
|
||||
DAG.getVTList(MVT::f32, MVT::Other),
|
||||
{Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
|
||||
else
|
||||
FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
|
||||
DAG.getIntPtrConstant(0, dl));
|
||||
@ -8747,8 +8768,9 @@ SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
|
||||
Chain = FP.getValue(1);
|
||||
if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
|
||||
if (IsStrict)
|
||||
FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl, {MVT::f32, MVT::Other},
|
||||
{Chain, FP, DAG.getIntPtrConstant(0, dl)});
|
||||
FP = DAG.getNode(ISD::STRICT_FP_ROUND, dl,
|
||||
DAG.getVTList(MVT::f32, MVT::Other),
|
||||
{Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
|
||||
else
|
||||
FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
|
||||
DAG.getIntPtrConstant(0, dl));
|
||||
|
@ -835,9 +835,9 @@ define void @fptoint_nofpexcept(ppc_fp128 %p, fp128 %m, i32* %addr1, i64* %addr2
|
||||
; MIR: renamable $v{{[0-9]+}} = nofpexcept XSCVQPUDZ
|
||||
;
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept FADD
|
||||
; MIR: renamable $f{{[0-9]+}} = XSCVDPSXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept FADD
|
||||
; MIR: renamable $f{{[0-9]+}} = XSCVDPSXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
|
||||
entry:
|
||||
%conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.ignore") #0
|
||||
store volatile i32 %conv1, i32* %addr1, align 4
|
||||
|
@ -6,6 +6,8 @@
|
||||
; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
|
||||
; RUN: < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 -mattr=-vsx | \
|
||||
; RUN: FileCheck %s -check-prefix=NOVSX
|
||||
; RUN: llc -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 < %s -simplify-mir \
|
||||
; RUN: -stop-after=machine-cp | FileCheck %s -check-prefix=MIR
|
||||
|
||||
declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
|
||||
declare i64 @llvm.experimental.constrained.fptosi.i64.f64(double, metadata)
|
||||
@ -326,4 +328,86 @@ entry:
|
||||
ret float %conv
|
||||
}
|
||||
|
||||
define void @fptoint_nofpexcept_f64(double %m, i32* %addr1, i64* %addr2) {
|
||||
; MIR-LABEL: name: fptoint_nofpexcept_f64
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS
|
||||
entry:
|
||||
%conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %m, metadata !"fpexcept.ignore") #0
|
||||
%conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %m, metadata !"fpexcept.ignore") #0
|
||||
%conv3 = tail call i64 @llvm.experimental.constrained.fptosi.i64.f64(double %m, metadata !"fpexcept.ignore") #0
|
||||
%conv4 = tail call i64 @llvm.experimental.constrained.fptoui.i64.f64(double %m, metadata !"fpexcept.ignore") #0
|
||||
store volatile i32 %conv1, i32* %addr1, align 4
|
||||
store volatile i32 %conv2, i32* %addr1, align 4
|
||||
store volatile i64 %conv3, i64* %addr2, align 8
|
||||
store volatile i64 %conv4, i64* %addr2, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @fptoint_nofpexcept_f32(float %m, i32* %addr1, i64* %addr2) {
|
||||
; MIR-LABEL: name: fptoint_nofpexcept_f32
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS
|
||||
entry:
|
||||
%conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %m, metadata !"fpexcept.ignore") #0
|
||||
%conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %m, metadata !"fpexcept.ignore") #0
|
||||
%conv3 = tail call i64 @llvm.experimental.constrained.fptosi.i64.f32(float %m, metadata !"fpexcept.ignore") #0
|
||||
%conv4 = tail call i64 @llvm.experimental.constrained.fptoui.i64.f32(float %m, metadata !"fpexcept.ignore") #0
|
||||
store volatile i32 %conv1, i32* %addr1, align 4
|
||||
store volatile i32 %conv2, i32* %addr1, align 4
|
||||
store volatile i64 %conv3, i64* %addr2, align 8
|
||||
store volatile i64 %conv4, i64* %addr2, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @inttofp_nofpexcept_i32(i32 %m, float* %addr1, double* %addr2) {
|
||||
; MIR-LABEL: name: inttofp_nofpexcept_i32
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP
|
||||
entry:
|
||||
%conv1 = tail call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv2 = tail call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv3 = tail call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv4 = tail call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
store volatile float %conv1, float* %addr1, align 4
|
||||
store volatile float %conv2, float* %addr1, align 4
|
||||
store volatile double %conv3, double* %addr2, align 8
|
||||
store volatile double %conv4, double* %addr2, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @inttofp_nofpexcept_i64(i64 %m, float* %addr1, double* %addr2) {
|
||||
; MIR-LABEL: name: inttofp_nofpexcept_i64
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP
|
||||
; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP
|
||||
entry:
|
||||
%conv1 = tail call float @llvm.experimental.constrained.sitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv2 = tail call float @llvm.experimental.constrained.uitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv3 = tail call double @llvm.experimental.constrained.sitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
%conv4 = tail call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
store volatile float %conv1, float* %addr1, align 4
|
||||
store volatile float %conv2, float* %addr1, align 4
|
||||
store volatile double %conv3, double* %addr2, align 8
|
||||
store volatile double %conv4, double* %addr2, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
define <2 x double> @inttofp_nofpexcept_vec(<2 x i16> %m) {
|
||||
; MIR-LABEL: name: inttofp_nofpexcept_vec
|
||||
; MIR: renamable $v{{[0-9]+}} = nofpexcept XVCVSXDDP
|
||||
entry:
|
||||
%conv = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16> %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
|
||||
ret <2 x double> %conv
|
||||
}
|
||||
|
||||
declare <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16>, metadata, metadata)
|
||||
|
||||
attributes #0 = { strictfp }
|
||||
|
Loading…
x
Reference in New Issue
Block a user