Skip to content

Commit

Permalink
DAG: Add new control for ISD::FMAD formation
Browse files Browse the repository at this point in the history
For AMDGPU this depends on whether denormals are enabled in the
default FP mode for the function. Currently this is treated as a
subtarget feature, so FMAD is selectively legal based on that. I want
to move this out of the subtarget features so this can be controlled
with a denormal mode attribute. Additionally, this will allow folding
based on a future ftz fast math flag.
  • Loading branch information
arsenm committed Oct 31, 2019
1 parent bc56166 commit 1725f28
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Expand Up @@ -2541,6 +2541,14 @@ class TargetLoweringBase {
return false;
}

/// Returns true if the FADD or FSUB node passed could legally be combined with
/// an fmul to form an ISD::FMAD.
virtual bool isFMADLegalForFAddFSub(const SelectionDAG &DAG,
const SDNode *N) const {
assert(N->getOpcode() == ISD::FADD || N->getOpcode() == ISD::FSUB);
return isOperationLegal(ISD::FMAD, N->getValueType(0));
}

/// Return true if it's profitable to narrow operations of type VT1 to
/// VT2. e.g. on x86, it's profitable to narrow from i32 to i8 but not from
/// i32 to i16.
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Expand Up @@ -11330,7 +11330,7 @@ SDValue DAGCombiner::visitFADDForFMACombine(SDNode *N) {
const TargetOptions &Options = DAG.getTarget().Options;

// Floating-point multiply-add with intermediate rounding.
bool HasFMAD = (LegalOperations && TLI.isOperationLegal(ISD::FMAD, VT));
bool HasFMAD = (LegalOperations && TLI.isFMADLegalForFAddFSub(DAG, N));

// Floating-point multiply-add without intermediate rounding.
bool HasFMA =
Expand Down Expand Up @@ -11541,7 +11541,7 @@ SDValue DAGCombiner::visitFSUBForFMACombine(SDNode *N) {

const TargetOptions &Options = DAG.getTarget().Options;
// Floating-point multiply-add with intermediate rounding.
bool HasFMAD = (LegalOperations && TLI.isOperationLegal(ISD::FMAD, VT));
bool HasFMAD = (LegalOperations && TLI.isFMADLegalForFAddFSub(DAG, N));

// Floating-point multiply-add without intermediate rounding.
bool HasFMA =
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Expand Up @@ -3939,6 +3939,19 @@ bool SITargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const {
return false;
}

bool SITargetLowering::isFMADLegalForFAddFSub(const SelectionDAG &DAG,
const SDNode *N) const {
// TODO: Check future ftz flag
// v_mad_f32/v_mac_f32 do not support denormals.
EVT VT = N->getValueType(0);
if (VT == MVT::f32)
return !Subtarget->hasFP32Denormals();
if (VT == MVT::f16)
return !Subtarget->hasFP16Denormals() && Subtarget->hasMadF16();

return false;
}

//===----------------------------------------------------------------------===//
// Custom DAG Lowering Operations
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AMDGPU/SIISelLowering.h
Expand Up @@ -349,6 +349,9 @@ class SITargetLowering final : public AMDGPUTargetLowering {
EVT VT) const override;
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override;
bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
bool isFMADLegalForFAddFSub(const SelectionDAG &DAG,
const SDNode *N) const override;

SDValue splitUnaryVectorOp(SDValue Op, SelectionDAG &DAG) const;
SDValue splitBinaryVectorOp(SDValue Op, SelectionDAG &DAG) const;
SDValue splitTernaryVectorOp(SDValue Op, SelectionDAG &DAG) const;
Expand Down

0 comments on commit 1725f28

Please sign in to comment.