diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -15763,8 +15763,9 @@ // 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)); } } @@ -15822,11 +15823,11 @@ 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! } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3251,8 +3251,9 @@ 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)); } @@ -4696,7 +4697,7 @@ 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; @@ -4756,8 +4757,9 @@ 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: @@ -4787,7 +4789,7 @@ 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}, @@ -4817,8 +4819,9 @@ // (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: @@ -4850,8 +4853,9 @@ 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: diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -1071,8 +1071,9 @@ 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); @@ -2532,7 +2533,8 @@ // 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) { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -594,7 +594,8 @@ 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); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1341,7 +1341,8 @@ 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 diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -4007,7 +4007,8 @@ {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) { @@ -7776,7 +7777,8 @@ 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 = @@ -8696,8 +8698,9 @@ 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); @@ -19501,10 +19504,11 @@ 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! } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -2456,7 +2456,8 @@ 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); @@ -2496,7 +2497,8 @@ 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); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -8661,7 +8661,7 @@ {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; } @@ -8742,7 +8742,7 @@ {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; } @@ -14063,9 +14063,9 @@ 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 @@ -14541,8 +14541,8 @@ 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()); } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -3367,7 +3367,7 @@ 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(); } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3463,7 +3463,7 @@ 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() && @@ -21603,7 +21603,7 @@ } 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 @@ -23221,8 +23221,8 @@ // 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. diff --git a/llvm/test/CodeGen/AArch64/sve-fcopysign.ll b/llvm/test/CodeGen/AArch64/sve-fcopysign.ll --- a/llvm/test/CodeGen/AArch64/sve-fcopysign.ll +++ b/llvm/test/CodeGen/AArch64/sve-fcopysign.ll @@ -207,6 +207,39 @@ ret %r } + +;========== FCOPYSIGN_EXTEND_ROUND + +define @test_copysign_nxv4f32_nxv4f16( %a, %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 @llvm.copysign.v4f32( %a, %b) + %t2 = fptrunc %t1 to + ret %t2 +} + +define @test_copysign_nxv2f64_nxv2f32( %a, %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 @llvm.copysign.v2f64( %a, %b) + %t2 = fptrunc %t1 to + ret %t2 +} + declare @llvm.copysign.v8f16( %a, %b) #0 attributes #0 = { nounwind }