diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -924,9 +924,9 @@ SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef Ops, const SDNodeFlags Flags = SDNodeFlags()); SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef ResultTys, - ArrayRef Ops); + ArrayRef Ops, const SDNodeFlags Flags = SDNodeFlags()); SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, - ArrayRef Ops); + ArrayRef Ops, const SDNodeFlags Flags = SDNodeFlags()); // Specialize based on number of operands. SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT); 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 @@ -2526,11 +2526,13 @@ // Okay, we found the operation and type to use. Zero extend our input to the // desired type then run the operation on it. if (IsStrict) { + SDNodeFlags Flags; + Flags.setFPExcept(N->getFlags().hasFPExcept()); SDValue Res = DAG.getNode(OpToUse, dl, {DestVT, MVT::Other}, {N->getOperand(0), DAG.getNode(IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, - dl, NewInTy, LegalOp)}); + dl, NewInTy, LegalOp)}, Flags); Results.push_back(Res); Results.push_back(Res.getValue(1)); } @@ -2580,8 +2582,10 @@ // Okay, we found the operation and type to use. SDValue Operation; if (IsStrict) { - SDVTList VTs = DAG.getVTList(NewOutTy, MVT::Other); - Operation = DAG.getNode(OpToUse, dl, VTs, N->getOperand(0), LegalOp); + SDNodeFlags Flags; + Flags.setFPExcept(N->getFlags().hasFPExcept()); + Operation = DAG.getNode(OpToUse, dl, { NewOutTy, MVT::Other }, + { N->getOperand(0), LegalOp }, Flags); } else Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -219,7 +219,8 @@ Opers[i] = Oper; } - SDValue Result = DAG.getNode(N->getOpcode(), dl, ValueVTs, Opers); + SDValue Result = DAG.getNode(N->getOpcode(), dl, ValueVTs, Opers, + N->getFlags()); // Legalize the chain result - switch anything that used the old chain to // use the new one. @@ -1285,10 +1286,11 @@ OpsHi[i] = OpHi; } + const SDNodeFlags Flags = N->getFlags(); EVT LoValueVTs[] = {LoVT, MVT::Other}; EVT HiValueVTs[] = {HiVT, MVT::Other}; - Lo = DAG.getNode(N->getOpcode(), dl, LoValueVTs, OpsLo); - Hi = DAG.getNode(N->getOpcode(), dl, HiValueVTs, OpsHi); + Lo = DAG.getNode(N->getOpcode(), dl, LoValueVTs, OpsLo, Flags); + Hi = DAG.getNode(N->getOpcode(), dl, HiValueVTs, OpsHi, Flags); // Build a factor node to remember that this Op is independent of the // other one. @@ -1336,8 +1338,8 @@ Operands[j] = Operand; } } - SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands); - Scalar.getNode()->setFlags(N->getFlags()); + SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands, + N->getFlags()); //Add in the scalar as well as its chain value to the //result vectors. 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 @@ -7350,14 +7350,15 @@ } SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, - ArrayRef ResultTys, ArrayRef Ops) { - return getNode(Opcode, DL, getVTList(ResultTys), Ops); + ArrayRef ResultTys, ArrayRef Ops, + const SDNodeFlags Flags) { + return getNode(Opcode, DL, getVTList(ResultTys), Ops, Flags); } SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, - ArrayRef Ops) { + ArrayRef Ops, const SDNodeFlags Flags) { if (VTList.NumVTs == 1) - return getNode(Opcode, DL, VTList.VTs[0], Ops); + return getNode(Opcode, DL, VTList.VTs[0], Ops, Flags); switch (Opcode) { case ISD::STRICT_FP_EXTEND: @@ -7420,10 +7421,13 @@ FoldingSetNodeID ID; AddNodeIDNode(ID, Opcode, VTList, Ops); void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) + if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) { + E->intersectFlagsWith(Flags); return SDValue(E, 0); + } N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList); + N->setFlags(Flags); createOperands(N, Ops); CSEMap.InsertNode(N, IP); } else { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -6065,8 +6065,10 @@ if (APFloat::opOverflow & APF.convertFromAPInt(SignMask, false, APFloat::rmNearestTiesToEven)) { if (Node->isStrictFPOpcode()) { + SDNodeFlags Flags; + Flags.setFPExcept(Node->getFlags().hasFPExcept()); Result = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other }, - { Node->getOperand(0), Src }); + { Node->getOperand(0), Src }, Flags); Chain = Result.getValue(1); } else Result = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src); @@ -6074,6 +6076,7 @@ } SDValue Cst = DAG.getConstantFP(APF, dl, SrcVT); + // FIXME: Does this need to be a strict comparision? SDValue Sel = DAG.getSetCC(dl, SetCCVT, Src, Cst, ISD::SETLT); bool Strict = Node->isStrictFPOpcode() || @@ -6095,10 +6098,12 @@ DAG.getConstant(SignMask, dl, DstVT)); SDValue SInt; if (Node->isStrictFPOpcode()) { + SDNodeFlags Flags; + Flags.setFPExcept(Node->getFlags().hasFPExcept()); SDValue Val = DAG.getNode(ISD::STRICT_FSUB, dl, { SrcVT, MVT::Other }, - { Node->getOperand(0), Src, FltOfs }); + { Node->getOperand(0), Src, FltOfs }, Flags); SInt = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { DstVT, MVT::Other }, - { Val.getValue(1), Val }); + { Val.getValue(1), Val }, Flags); Chain = SInt.getValue(1); } else { SDValue Val = DAG.getNode(ISD::FSUB, dl, SrcVT, Src, FltOfs); 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 @@ -18577,9 +18577,12 @@ // SSE doesn't have an i16 conversion so we need to promote. if (SrcVT == MVT::i16 && (UseSSEReg || VT == MVT::f128)) { SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i32, Src); - if (IsStrict) + if (IsStrict) { + SDNodeFlags Flags; + Flags.setFPExcept(Op->getFlags().hasFPExcept()); return DAG.getNode(ISD::STRICT_SINT_TO_FP, dl, {VT, MVT::Other}, - {Op.getOperand(0), Ext}); + {Op.getOperand(0), Ext}, Flags); + } return DAG.getNode(ISD::SINT_TO_FP, dl, VT, Ext); } @@ -19184,6 +19187,7 @@ SDValue ThreshVal = DAG.getConstantFP(Thresh, DL, TheVT); + // FIXME: Does this need to be a strict compare? SDValue Cmp = DAG.getSetCC(DL, getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), TheVT), @@ -19197,8 +19201,10 @@ ThreshVal); if (IsStrict) { + SDNodeFlags Flags; + Flags.setFPExcept(Op->getFlags().hasFPExcept()); Value = DAG.getNode(ISD::STRICT_FSUB, DL, { TheVT, MVT::Other}, - { Chain, Value, FltOfs }); + { Chain, Value, FltOfs }, Flags); Chain = Value.getValue(1); } else Value = DAG.getNode(ISD::FSUB, DL, TheVT, Value, FltOfs); @@ -19226,6 +19232,7 @@ MachineMemOperand *MMO = MF.getMachineMemOperand( MPI, MachineMemOperand::MOStore, MemSize, MemSize); SDValue Ops[] = { Chain, Value, StackSlot }; + // FIXME: How do we get the fpexcept flag onto this node? SDValue FIST = DAG.getMemIntrinsicNode(X86ISD::FP_TO_INT_IN_MEM, DL, DAG.getVTList(MVT::Other), Ops, DstTy, MMO); @@ -19790,8 +19797,10 @@ if (Subtarget.is64Bit()) { SDValue Res, Chain; if (IsStrict) { + SDNodeFlags Flags; + Flags.setFPExcept(Op->getFlags().hasFPExcept()); Res = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { MVT::i64, MVT::Other}, - { Op.getOperand(0), Src }); + { Op.getOperand(0), Src }, Flags); Chain = Res.getValue(1); } else Res = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i64, Src); @@ -19815,8 +19824,10 @@ assert(IsSigned && "Expected i16 FP_TO_UINT to have been promoted!"); SDValue Res, Chain; if (IsStrict) { + SDNodeFlags Flags; + Flags.setFPExcept(Op->getFlags().hasFPExcept()); Res = DAG.getNode(ISD::STRICT_FP_TO_SINT, dl, { MVT::i32, MVT::Other}, - { Op.getOperand(0), Src }); + { Op.getOperand(0), Src }, Flags); Chain = Res.getValue(1); } else Res = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Src);