llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-selectiondag Author: Serge Pavlov (spavloff) <details> <summary>Changes</summary> FP operations listed in FloatingPointOps.def are now lowered to DAG in the same way as constrained intrinsics, using special DAG nodes like STRICT_NEARBYINT. This is a temporary solution. Existing nodes like STRICT_NEARBYINT cannot carry information about rounding or other control modes, so they cannot implement static rounding, for example. However they can serve as a first step toward a solution based on the FP operand bundles. --- Full diff: https://github.com/llvm/llvm-project/pull/138553.diff 3 Files Affected: - (modified) llvm/include/llvm/IR/FloatingPointOps.def (+6-1) - (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+58-4) - (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (+1) ``````````diff diff --git a/llvm/include/llvm/IR/FloatingPointOps.def b/llvm/include/llvm/IR/FloatingPointOps.def index 468227e648300..6d653668fe340 100644 --- a/llvm/include/llvm/IR/FloatingPointOps.def +++ b/llvm/include/llvm/IR/FloatingPointOps.def @@ -14,12 +14,17 @@ #define FUNCTION(N,D) #endif +#ifndef CONSTRAINED +#define CONSTRAINED(N,D) FUNCTION(N,D) +#endif + // Arguments of the entries are: // - intrinsic function name, // - DAG node corresponding to the intrinsic. -FUNCTION(experimental_constrained_fadd, FADD) +CONSTRAINED(experimental_constrained_fadd, FADD) FUNCTION(nearbyint, FNEARBYINT) FUNCTION(trunc, FTRUNC) #undef FUNCTION +#undef CONSTRAINED diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 8cae34d06c8ba..cd97338cfaa93 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6802,9 +6802,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, case Intrinsic::exp10: case Intrinsic::floor: case Intrinsic::ceil: - case Intrinsic::trunc: case Intrinsic::rint: - case Intrinsic::nearbyint: case Intrinsic::round: case Intrinsic::roundeven: case Intrinsic::canonicalize: { @@ -6826,9 +6824,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, case Intrinsic::exp10: Opcode = ISD::FEXP10; break; case Intrinsic::floor: Opcode = ISD::FFLOOR; break; case Intrinsic::ceil: Opcode = ISD::FCEIL; break; - case Intrinsic::trunc: Opcode = ISD::FTRUNC; break; case Intrinsic::rint: Opcode = ISD::FRINT; break; - case Intrinsic::nearbyint: Opcode = ISD::FNEARBYINT; break; case Intrinsic::round: Opcode = ISD::FROUND; break; case Intrinsic::roundeven: Opcode = ISD::FROUNDEVEN; break; case Intrinsic::canonicalize: Opcode = ISD::FCANONICALIZE; break; @@ -6959,6 +6955,11 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, #include "llvm/IR/ConstrainedOps.def" visitConstrainedFPIntrinsic(cast<ConstrainedFPIntrinsic>(I)); return; +#define CONSTRAINED(INTRINSIC, DAGN) +#define FUNCTION(INTRINSIC, DAGN) case Intrinsic::INTRINSIC: +#include "llvm/IR/FloatingPointOps.def" + visitFPOperationIntrinsic(I, Intrinsic); + return; #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: #include "llvm/IR/VPIntrinsics.def" visitVectorPredicationIntrinsic(cast<VPIntrinsic>(I)); @@ -8350,6 +8351,59 @@ void SelectionDAGBuilder::visitConstrainedFPIntrinsic( setValue(&FPI, FPResult); } +void SelectionDAGBuilder::visitFPOperationIntrinsic(const CallInst &CI, + unsigned Intrinsic) { + SDLoc sdl = getCurSDLoc(); + bool StrictFP = + FuncInfo.Fn->getAttributes().hasFnAttr(llvm::Attribute::StrictFP); + + int Opcode = -1; + switch (Intrinsic) { +#define CONSTRAINED(NAME, DAGN) +#define FUNCTION(NAME, DAGN) \ + case Intrinsic::NAME: \ + Opcode = StrictFP ? ISD::STRICT_##DAGN : ISD::DAGN; \ + break; +#include "llvm/IR/FloatingPointOps.def" + } + + SDNodeFlags Flags; + if (CI.getExceptionBehavior() == fp::ExceptionBehavior::ebIgnore) + Flags.setNoFPExcept(true); + if (auto *FPOp = dyn_cast<FPMathOperator>(&CI)) + Flags.copyFMF(*FPOp); + + SmallVector<SDValue, 4> Operands; + if (StrictFP) + Operands.push_back(DAG.getRoot()); + for (unsigned I = 0, E = CI.arg_size(); I != E; ++I) + Operands.push_back(getValue(CI.getArgOperand(I))); + + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + EVT VT = TLI.getValueType(DAG.getDataLayout(), CI.getType()); + SDVTList VTs = StrictFP ? DAG.getVTList(VT, MVT::Other) : DAG.getVTList(VT); + + SDValue Result = DAG.getNode(Opcode, sdl, VTs, Operands, Flags); + + SDValue OutChain; + if (StrictFP) { + OutChain = Result.getValue(1); + switch (CI.getExceptionBehavior()) { + case fp::ExceptionBehavior::ebIgnore: + case fp::ExceptionBehavior::ebMayTrap: + PendingConstrainedFP.push_back(OutChain); + break; + case fp::ExceptionBehavior::ebStrict: + PendingConstrainedFPStrict.push_back(OutChain); + break; + } + SDValue FPResult = Result.getValue(0); + setValue(&CI, FPResult); + } else { + setValue(&CI, Result); + } +} + static unsigned getISDForVPIntrinsic(const VPIntrinsic &VPIntrin) { std::optional<unsigned> ResOPC; switch (VPIntrin.getIntrinsicID()) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 35c15bc269d4b..fcd5a4da9e8d9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -627,6 +627,7 @@ class SelectionDAGBuilder { void visitIntrinsicCall(const CallInst &I, unsigned Intrinsic); void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI); + void visitFPOperationIntrinsic(const CallInst &I, unsigned Intrinsic); void visitConvergenceControl(const CallInst &I, unsigned Intrinsic); void visitVectorHistogram(const CallInst &I, unsigned IntrinsicID); void visitVectorExtractLastActive(const CallInst &I, unsigned Intrinsic); `````````` </details> https://github.com/llvm/llvm-project/pull/138553 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits