// Also, this is a value preserving truncation iff both fp_round's are.
if (DAG.getTarget().Options.UnsafeFPMath || N0IsTrunc) {
SDLoc DL(N);
- return DAG.getNode(ISD::FP_ROUND, DL, VT, N0.getOperand(0),
- DAG.getIntPtrConstant(NIsTrunc && N0IsTrunc, DL));
+ return DAG.getNode(
+ ISD::FP_ROUND, DL, VT, N0.getOperand(0),
+ DAG.getIntPtrConstant(NIsTrunc && N0IsTrunc, DL, /*isTarget=*/true));
}
}
LN0->getBasePtr(), N0.getValueType(),
LN0->getMemOperand());
CombineTo(N, ExtLoad);
- CombineTo(N0.getNode(),
- DAG.getNode(ISD::FP_ROUND, SDLoc(N0),
- N0.getValueType(), ExtLoad,
- DAG.getIntPtrConstant(1, SDLoc(N0))),
- ExtLoad.getValue(1));
+ CombineTo(
+ N0.getNode(),
+ DAG.getNode(ISD::FP_ROUND, SDLoc(N0), N0.getValueType(), ExtLoad,
+ DAG.getIntPtrConstant(1, SDLoc(N0), /*isTarget=*/true)),
+ ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
TLI.isOperationLegalOrCustom(ISD::FP_TO_FP16, MVT::f32)) {
// Under fastmath, we can expand this node into a fround followed by
// a float-half conversion.
- SDValue FloatVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Op,
- DAG.getIntPtrConstant(0, dl));
+ SDValue FloatVal =
+ DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Op,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
Results.push_back(
DAG.getNode(ISD::FP_TO_FP16, dl, Node->getValueType(0), FloatVal));
}
Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1);
else
Tmp1 = DAG.getNode(ISD::FP_ROUND, dl, OVT, Tmp1,
- DAG.getIntPtrConstant(0, dl));
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
Results.push_back(Tmp1);
break;
Tmp2 = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(1));
Tmp3 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2,
Node->getFlags());
- Results.push_back(DAG.getNode(ISD::FP_ROUND, dl, OVT,
- Tmp3, DAG.getIntPtrConstant(0, dl)));
+ Results.push_back(
+ DAG.getNode(ISD::FP_ROUND, dl, OVT, Tmp3,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)));
break;
case ISD::STRICT_FADD:
case ISD::STRICT_FSUB:
Results.push_back(
DAG.getNode(ISD::FP_ROUND, dl, OVT,
DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2, Tmp3),
- DAG.getIntPtrConstant(0, dl)));
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)));
break;
case ISD::STRICT_FMA:
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other},
// (fp_round (fpext a))
// which is a no-op. Mark it as a TRUNCating FP_ROUND.
const bool isTrunc = (Node->getOpcode() == ISD::FCOPYSIGN);
- Results.push_back(DAG.getNode(ISD::FP_ROUND, dl, OVT,
- Tmp3, DAG.getIntPtrConstant(isTrunc, dl)));
+ Results.push_back(
+ DAG.getNode(ISD::FP_ROUND, dl, OVT, Tmp3,
+ DAG.getIntPtrConstant(isTrunc, dl, /*isTarget=*/true)));
break;
}
case ISD::STRICT_FPOWI:
case ISD::FEXP2:
Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Node->getOperand(0));
Tmp2 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1);
- Results.push_back(DAG.getNode(ISD::FP_ROUND, dl, OVT,
- Tmp2, DAG.getIntPtrConstant(0, dl)));
+ Results.push_back(
+ DAG.getNode(ISD::FP_ROUND, dl, OVT, Tmp2,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)));
break;
case ISD::STRICT_FFLOOR:
case ISD::STRICT_FCEIL:
if (ST->isTruncatingStore())
// Do an FP_ROUND followed by a non-truncating store.
- Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(),
- Val, DAG.getIntPtrConstant(0, dl)));
+ Val = BitConvertToInteger(
+ DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), Val,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)));
else
Val = GetSoftenedFloat(Val);
// Round the value to the desired precision (that of the source type).
return DAG.getNode(
ISD::FP_EXTEND, DL, NVT,
- DAG.getNode(ISD::FP_ROUND, DL, VT, NV, DAG.getIntPtrConstant(0, DL)));
+ DAG.getNode(ISD::FP_ROUND, DL, VT, NV,
+ DAG.getIntPtrConstant(0, DL, /*isTarget=*/true)));
}
SDValue DAGTypeLegalizer::PromoteFloatRes_UNDEF(SDNode *N) {
if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
(VT.isVector() && VT.getVectorElementType().isFloatingPoint() &&
NVT.isVector() && NVT.getVectorElementType().isFloatingPoint()))
- Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res, DAG.getIntPtrConstant(0, dl));
+ Res = DAG.getNode(ISD::FP_ROUND, dl, VT, Res,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
else
Res = DAG.getNode(ISD::BITCAST, dl, VT, Res);
SDValue SelectionDAG::getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT) {
return VT.bitsGT(Op.getValueType())
? getNode(ISD::FP_EXTEND, DL, VT, Op)
- : getNode(ISD::FP_ROUND, DL, VT, Op, getIntPtrConstant(0, DL));
+ : getNode(ISD::FP_ROUND, DL, VT, Op,
+ getIntPtrConstant(0, DL, /*isTarget=*/true));
}
std::pair<SDValue, SDValue>
{In.getValue(1), In.getValue(0), DAG.getIntPtrConstant(0, dl)});
}
In = DAG.getNode(Opc, dl, CastVT, In);
- return DAG.getNode(ISD::FP_ROUND, dl, VT, In, DAG.getIntPtrConstant(0, dl));
+ return DAG.getNode(ISD::FP_ROUND, dl, VT, In,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
}
if (VTSize > InVTSize) {
if (SrcVT.bitsLT(VT))
In2 = DAG.getNode(ISD::FP_EXTEND, DL, VT, In2);
else if (SrcVT.bitsGT(VT))
- In2 = DAG.getNode(ISD::FP_ROUND, DL, VT, In2, DAG.getIntPtrConstant(0, DL));
+ In2 = DAG.getNode(ISD::FP_ROUND, DL, VT, In2,
+ DAG.getIntPtrConstant(0, DL, /*isTarget=*/true));
if (VT.isScalableVector())
IntVT =
SDValue WideFP =
DAG.getLoad(MVT::f64, DL, APStore, VAList, MachinePointerInfo());
// Round the value down to an f32.
- SDValue NarrowFP = DAG.getNode(ISD::FP_ROUND, DL, VT, WideFP.getValue(0),
- DAG.getIntPtrConstant(1, DL));
+ SDValue NarrowFP =
+ DAG.getNode(ISD::FP_ROUND, DL, VT, WideFP.getValue(0),
+ DAG.getIntPtrConstant(1, DL, /*isTarget=*/true));
SDValue Ops[] = { NarrowFP, WideFP.getValue(1) };
// Merge the rounded value with the chain output of the load.
return DAG.getMergeValues(Ops, DL);
LN0->getChain(), LN0->getBasePtr(),
N0.getValueType(), LN0->getMemOperand());
DCI.CombineTo(N, ExtLoad);
- DCI.CombineTo(N0.getNode(),
- DAG.getNode(ISD::FP_ROUND, SDLoc(N0), N0.getValueType(),
- ExtLoad, DAG.getIntPtrConstant(1, SDLoc(N0))),
- ExtLoad.getValue(1));
+ DCI.CombineTo(
+ N0.getNode(),
+ DAG.getNode(ISD::FP_ROUND, SDLoc(N0), N0.getValueType(), ExtLoad,
+ DAG.getIntPtrConstant(1, SDLoc(N0), /*isTarget=*/true)),
+ ExtLoad.getValue(1));
return SDValue(N, 0); // Return N so it doesn't get rechecked!
}
SDLoc DL(Op);
SDValue IntToFp32 = DAG.getNode(Op.getOpcode(), DL, MVT::f32, Src);
- SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SDLoc(Op));
+ SDValue FPRoundFlag =
+ DAG.getIntPtrConstant(0, SDLoc(Op), /*isTarget=*/true);
SDValue FPRound =
DAG.getNode(ISD::FP_ROUND, DL, MVT::f16, IntToFp32, FPRoundFlag);
SDValue Src = Op.getOperand(0);
SDValue IntToFp32 = DAG.getNode(Op.getOpcode(), DL, MVT::f32, Src);
- SDValue FPRoundFlag = DAG.getIntPtrConstant(0, SDLoc(Op));
+ SDValue FPRoundFlag =
+ DAG.getIntPtrConstant(0, SDLoc(Op), /*isTarget=*/true);
SDValue FPRound =
DAG.getNode(ISD::FP_ROUND, DL, MVT::f16, IntToFp32, FPRoundFlag);
{Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
else
FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
- DAG.getIntPtrConstant(0, dl));
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
}
return FP;
}
{Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
else
FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
- DAG.getIntPtrConstant(0, dl));
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
}
return FP;
}
if (In.isUndef())
Ops.push_back(DAG.getUNDEF(SrcVT));
else {
- SDValue Trunc = DAG.getNode(ISD::FP_ROUND, dl,
- MVT::f32, In.getOperand(0),
- DAG.getIntPtrConstant(1, dl));
+ SDValue Trunc =
+ DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, In.getOperand(0),
+ DAG.getIntPtrConstant(1, dl, /*isTarget=*/true));
Ops.push_back(Trunc);
}
} else
SDValue FP = DAG.getNode(FCFOp, dl, FCFTy, Tmp);
if (Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
- FP = DAG.getNode(ISD::FP_ROUND, dl,
- MVT::f32, FP, DAG.getIntPtrConstant(0, dl));
+ FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
DCI.AddToWorklist(FP.getNode());
}
SDValue Powi =
DAG.getNode(ISD::FPOWI, DL, MVT::f32, Op0, Op.getOperand(1));
return DAG.getNode(ISD::FP_ROUND, DL, MVT::f16, Powi,
- DAG.getIntPtrConstant(0, DL));
+ DAG.getIntPtrConstant(0, DL, /*isTarget=*/true));
}
return SDValue();
}
if (RoundAfterCopy)
Val = DAG.getNode(ISD::FP_ROUND, dl, VA.getValVT(), Val,
// This truncation won't change the value.
- DAG.getIntPtrConstant(1, dl));
+ DAG.getIntPtrConstant(1, dl, /*isTarget=*/true));
if (VA.isExtInLoc()) {
if (VA.getValVT().isVector() &&
}
SDValue Add = DAG.getNode(ISD::FADD, dl, MVT::f80, Fild, Fudge);
return DAG.getNode(ISD::FP_ROUND, dl, DstVT, Add,
- DAG.getIntPtrConstant(0, dl));
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
}
// If the given FP_TO_SINT (IsSigned) or FP_TO_UINT (!IsSigned) operation
// And if it is bigger, shrink it first.
if (Sign.getSimpleValueType().bitsGT(VT))
- Sign =
- DAG.getNode(ISD::FP_ROUND, dl, VT, Sign, DAG.getIntPtrConstant(0, dl));
+ Sign = DAG.getNode(ISD::FP_ROUND, dl, VT, Sign,
+ DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
// At this point the operands and the result should have the same
// type, and that won't be f80 since that is not custom lowered.
ret <vscale x 8 x half> %r
}
+
+;========== FCOPYSIGN_EXTEND_ROUND
+
+define <vscale x 4 x half> @test_copysign_nxv4f32_nxv4f16(<vscale x 4 x float> %a, <vscale x 4 x float> %b) #0 {
+; CHECK-LABEL: test_copysign_nxv4f32_nxv4f16:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.s
+; CHECK-NEXT: fcvt z0.h, p0/m, z0.s
+; CHECK-NEXT: fcvt z1.h, p0/m, z1.s
+; CHECK-NEXT: and z1.h, z1.h, #0x8000
+; CHECK-NEXT: and z0.h, z0.h, #0x7fff
+; CHECK-NEXT: orr z0.d, z0.d, z1.d
+; CHECK-NEXT: ret
+ %t1 = call <vscale x 4 x float> @llvm.copysign.v4f32(<vscale x 4 x float> %a, <vscale x 4 x float> %b)
+ %t2 = fptrunc <vscale x 4 x float> %t1 to <vscale x 4 x half>
+ ret <vscale x 4 x half> %t2
+}
+
+define <vscale x 2 x float> @test_copysign_nxv2f64_nxv2f32(<vscale x 2 x double> %a, <vscale x 2 x double> %b) #0 {
+; CHECK-LABEL: test_copysign_nxv2f64_nxv2f32:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.d
+; CHECK-NEXT: fcvt z0.s, p0/m, z0.d
+; CHECK-NEXT: fcvt z1.s, p0/m, z1.d
+; CHECK-NEXT: and z1.s, z1.s, #0x80000000
+; CHECK-NEXT: and z0.s, z0.s, #0x7fffffff
+; CHECK-NEXT: orr z0.d, z0.d, z1.d
+; CHECK-NEXT: ret
+ %t1 = call <vscale x 2 x double> @llvm.copysign.v2f64(<vscale x 2 x double> %a, <vscale x 2 x double> %b)
+ %t2 = fptrunc <vscale x 2 x double> %t1 to <vscale x 2 x float>
+ ret <vscale x 2 x float> %t2
+}
+
declare <vscale x 8 x half> @llvm.copysign.v8f16(<vscale x 8 x half> %a, <vscale x 8 x half> %b) #0
attributes #0 = { nounwind }