[llvm-branch-commits] [llvm] [SelectionDAG] Adaptation for FP operation lowering (PR #138553)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon May 5 09:43:32 PDT 2025
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
More information about the llvm-branch-commits
mailing list