@@ -6816,9 +6816,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
68166816 case Intrinsic::exp10:
68176817 case Intrinsic::floor:
68186818 case Intrinsic::ceil:
6819- case Intrinsic::trunc:
68206819 case Intrinsic::rint:
6821- case Intrinsic::nearbyint:
68226820 case Intrinsic::round:
68236821 case Intrinsic::roundeven:
68246822 case Intrinsic::canonicalize: {
@@ -6840,9 +6838,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
68406838 case Intrinsic::exp10: Opcode = ISD::FEXP10; break;
68416839 case Intrinsic::floor: Opcode = ISD::FFLOOR; break;
68426840 case Intrinsic::ceil: Opcode = ISD::FCEIL; break;
6843- case Intrinsic::trunc: Opcode = ISD::FTRUNC; break ;
68446841 case Intrinsic::rint: Opcode = ISD::FRINT; break;
6845- case Intrinsic::nearbyint: Opcode = ISD::FNEARBYINT; break ;
68466842 case Intrinsic::round: Opcode = ISD::FROUND; break;
68476843 case Intrinsic::roundeven: Opcode = ISD::FROUNDEVEN; break;
68486844 case Intrinsic::canonicalize: Opcode = ISD::FCANONICALIZE; break;
@@ -6977,6 +6973,11 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
69776973#include "llvm/IR/VPIntrinsics.def"
69786974 visitVectorPredicationIntrinsic(cast<VPIntrinsic>(I));
69796975 return;
6976+ #define FUNCTION(NAME, DAGN) \
6977+ case Intrinsic::NAME: \
6978+ visitFPOperation(I, ISD::DAGN); \
6979+ break;
6980+ #include "llvm/IR/FloatingPointOps.def"
69806981 case Intrinsic::fptrunc_round: {
69816982 // Get the last argument, the metadata and convert it to an integer in the
69826983 // call
@@ -8273,6 +8274,33 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
82738274 }
82748275}
82758276
8277+ void SelectionDAGBuilder::pushOutChain(SDValue Result,
8278+ fp::ExceptionBehavior EB) {
8279+ assert(Result.getNode()->getNumValues() == 2);
8280+
8281+ // Push node to the appropriate list so that future instructions can be
8282+ // chained up correctly.
8283+ SDValue OutChain = Result.getValue(1);
8284+ switch (EB) {
8285+ case fp::ExceptionBehavior::ebIgnore:
8286+ // The only reason why ebIgnore nodes still need to be chained is that
8287+ // they might depend on the current rounding mode, and therefore must
8288+ // not be moved across instruction that may change that mode.
8289+ [[fallthrough]];
8290+ case fp::ExceptionBehavior::ebMayTrap:
8291+ // These must not be moved across calls or instructions that may change
8292+ // floating-point exception masks.
8293+ PendingConstrainedFP.push_back(OutChain);
8294+ break;
8295+ case fp::ExceptionBehavior::ebStrict:
8296+ // These must not be moved across calls or instructions that may change
8297+ // floating-point exception masks or read floating-point exception flags.
8298+ // In addition, they cannot be optimized out even if unused.
8299+ PendingConstrainedFPStrict.push_back(OutChain);
8300+ break;
8301+ }
8302+ }
8303+
82768304void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
82778305 const ConstrainedFPIntrinsic &FPI) {
82788306 SDLoc sdl = getCurSDLoc();
@@ -8286,32 +8314,6 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic(
82868314 for (unsigned I = 0, E = FPI.getNonMetadataArgCount(); I != E; ++I)
82878315 Opers.push_back(getValue(FPI.getArgOperand(I)));
82888316
8289- auto pushOutChain = [this ](SDValue Result, fp::ExceptionBehavior EB) {
8290- assert (Result.getNode ()->getNumValues () == 2 );
8291-
8292- // Push node to the appropriate list so that future instructions can be
8293- // chained up correctly.
8294- SDValue OutChain = Result.getValue (1 );
8295- switch (EB) {
8296- case fp::ExceptionBehavior::ebIgnore:
8297- // The only reason why ebIgnore nodes still need to be chained is that
8298- // they might depend on the current rounding mode, and therefore must
8299- // not be moved across instruction that may change that mode.
8300- [[fallthrough]];
8301- case fp::ExceptionBehavior::ebMayTrap:
8302- // These must not be moved across calls or instructions that may change
8303- // floating-point exception masks.
8304- PendingConstrainedFP.push_back (OutChain);
8305- break ;
8306- case fp::ExceptionBehavior::ebStrict:
8307- // These must not be moved across calls or instructions that may change
8308- // floating-point exception masks or read floating-point exception flags.
8309- // In addition, they cannot be optimized out even if unused.
8310- PendingConstrainedFPStrict.push_back (OutChain);
8311- break ;
8312- }
8313- };
8314-
83158317 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
83168318 EVT VT = TLI.getValueType(DAG.getDataLayout(), FPI.getType());
83178319 SDVTList VTs = DAG.getVTList(VT, MVT::Other);
@@ -9355,6 +9357,56 @@ bool SelectionDAGBuilder::visitBinaryFloatCall(const CallInst &I,
93559357 return true;
93569358}
93579359
9360+ bool SelectionDAGBuilder::visitFPOperation(const CallInst &I, unsigned Opcode) {
9361+ // We already checked this call's prototype; verify it doesn't modify errno.
9362+ MemoryEffects ME = I.getMemoryEffects();
9363+ if (!ME.onlyAccessesInaccessibleMem())
9364+ return false;
9365+
9366+ SmallVector<SDValue, 4> Operands;
9367+ bool HasChain = ME.doesAccessInaccessibleMem();
9368+ if (HasChain)
9369+ Operands.push_back(getRoot());
9370+ for (auto &Arg : I.args())
9371+ Operands.push_back(getValue(Arg));
9372+
9373+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
9374+ EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType(), true);
9375+ SDVTList NodeVT;
9376+ if (HasChain)
9377+ NodeVT = DAG.getVTList(VT, MVT::Other);
9378+ else
9379+ NodeVT = DAG.getVTList(VT);
9380+
9381+ SDNodeFlags Flags;
9382+ fp::ExceptionBehavior EB = I.getExceptionBehavior();
9383+ if (EB == fp::ExceptionBehavior::ebIgnore)
9384+ Flags.setNoFPExcept(true);
9385+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
9386+ Flags.copyFMF(*FPOp);
9387+
9388+ // Temporary solution: use STRICT_* nodes.
9389+ if (HasChain)
9390+ switch (Opcode) {
9391+ default:
9392+ break;
9393+ #define LEGACY_DAG(NAME, DAGN) \
9394+ case ISD::DAGN: \
9395+ Opcode = ISD::STRICT_##DAGN; \
9396+ break;
9397+ #include "llvm/IR/FloatingPointOps.def"
9398+ }
9399+
9400+ SDLoc sdl = getCurSDLoc();
9401+ SDValue Result = DAG.getNode(Opcode, sdl, NodeVT, Operands, Flags);
9402+ if (HasChain)
9403+ pushOutChain(Result, EB);
9404+
9405+ SDValue FPResult = Result.getValue(0);
9406+ setValue(&I, FPResult);
9407+ return true;
9408+ }
9409+
93589410void SelectionDAGBuilder::visitCall(const CallInst &I) {
93599411 // Handle inline assembly differently.
93609412 if (I.isInlineAsm()) {
0 commit comments