mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 00:39:36 +00:00
Added TLI hook for isFPExtFree. Some of the FMA combine heuristics are now guarded with that hook.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
046c3e807d
commit
9dd21f4380
@ -1500,6 +1500,14 @@ public:
|
||||
return isZExtFree(Val.getValueType(), VT2);
|
||||
}
|
||||
|
||||
/// Return true if an fpext operation is free (for instance, because
|
||||
/// single-precision floating-point numbers are implicitly extended to
|
||||
/// double-precision).
|
||||
virtual bool isFPExtFree(EVT VT) const {
|
||||
assert(VT.isFloatingPoint());
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return true if an fneg operation is free to the point where it is never
|
||||
/// worthwhile to replace it with a bitwise operation.
|
||||
virtual bool isFNegFree(EVT VT) const {
|
||||
|
@ -6957,8 +6957,37 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
N1.getOperand(0), N1.getOperand(1), N0);
|
||||
|
||||
// When FP_EXTEND nodes are free on the target, and there is an opportunity
|
||||
// to combine into FMA, arrange such nodes accordingly.
|
||||
if (TLI.isFPExtFree(VT)) {
|
||||
|
||||
// fold (fadd (fpext (fmul x, y)), z) -> (fma (fpext x), (fpext y), z)
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(1)), N1);
|
||||
}
|
||||
|
||||
// fold (fadd x, (fpext (fmul y, z)), z) -> (fma (fpext y), (fpext z), x)
|
||||
// Note: Commutes FADD operands.
|
||||
if (N1.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N10 = N1.getOperand(0);
|
||||
if (N10.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(1)), N0);
|
||||
}
|
||||
}
|
||||
|
||||
// More folding opportunities when target permits.
|
||||
if (TLI.enableAggressiveFMAFusion(VT)) {
|
||||
|
||||
// fold (fadd (fma x, y, (fmul u, v)), z) -> (fma x, y (fma u, v, z))
|
||||
if (N0.getOpcode() == ISD::FMA &&
|
||||
N0.getOperand(2).getOpcode() == ISD::FMUL)
|
||||
@ -6978,32 +7007,6 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
||||
N1.getOperand(2).getOperand(0),
|
||||
N1.getOperand(2).getOperand(1),
|
||||
N0));
|
||||
|
||||
// Remove FP_EXTEND when there is an opportunity to combine. This is
|
||||
// legal here since extra precision is allowed.
|
||||
|
||||
// fold (fadd (fpext (fmul x, y)), z) -> (fma x, y, z)
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(1)), N1);
|
||||
}
|
||||
|
||||
// fold (fadd x, (fpext (fmul y, z)), z) -> (fma y, z, x)
|
||||
// Note: Commutes FADD operands.
|
||||
if (N1.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N10 = N1.getOperand(0);
|
||||
if (N10.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(1)), N0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7099,6 +7102,75 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
||||
DAG.getNode(ISD::FNEG, dl, VT, N1));
|
||||
}
|
||||
|
||||
// When FP_EXTEND nodes are free on the target, and there is an opportunity
|
||||
// to combine into FMA, arrange such nodes accordingly.
|
||||
if (TLI.isFPExtFree(VT)) {
|
||||
|
||||
// fold (fsub (fpext (fmul x, y)), z)
|
||||
// -> (fma (fpext x), (fpext y), (fneg z))
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT, N1));
|
||||
}
|
||||
|
||||
// fold (fsub x, (fpext (fmul y, z)))
|
||||
// -> (fma (fneg (fpext y)), (fpext z), x)
|
||||
// Note: Commutes FSUB operands.
|
||||
if (N1.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N10 = N1.getOperand(0);
|
||||
if (N10.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N10.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(1)),
|
||||
N0);
|
||||
}
|
||||
|
||||
// fold (fsub (fpext (fneg (fmul, x, y))), z)
|
||||
// -> (fma (fneg (fpext x)), (fpext y), (fneg z))
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FNEG) {
|
||||
SDValue N000 = N00.getOperand(0);
|
||||
if (N000.getOpcode() == ISD::FMUL) {
|
||||
return DAG.getNode(ISD::FMA, dl, VT,
|
||||
DAG.getNode(ISD::FNEG, dl, VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N000.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N000.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, dl, VT, N1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fold (fsub (fneg (fpext (fmul, x, y))), z)
|
||||
// -> (fma (fneg (fpext x)), (fpext y), (fneg z))
|
||||
if (N0.getOpcode() == ISD::FNEG) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N000 = N00.getOperand(0);
|
||||
if (N000.getOpcode() == ISD::FMUL) {
|
||||
return DAG.getNode(ISD::FMA, dl, VT,
|
||||
DAG.getNode(ISD::FNEG, dl, VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N000.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N000.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, dl, VT, N1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// More folding opportunities when target permits.
|
||||
if (TLI.enableAggressiveFMAFusion(VT)) {
|
||||
|
||||
@ -7129,71 +7201,6 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
||||
N20),
|
||||
N21, N0));
|
||||
}
|
||||
|
||||
// Remove FP_EXTEND when there is an opportunity to combine. This is
|
||||
// legal here since extra precision is allowed.
|
||||
|
||||
// fold (fsub (fpext (fmul x, y)), z) -> (fma x, y, (fneg z))
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(0)),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N00.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT, N1));
|
||||
}
|
||||
|
||||
// fold (fsub x, (fpext (fmul y, z))) -> (fma (fneg y), z, x)
|
||||
// Note: Commutes FSUB operands.
|
||||
if (N1.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N10 = N1.getOperand(0);
|
||||
if (N10.getOpcode() == ISD::FMUL)
|
||||
return DAG.getNode(ISD::FMA, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FNEG, SDLoc(N), VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N10.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N10.getOperand(1)),
|
||||
N0);
|
||||
}
|
||||
|
||||
// fold (fsub (fpext (fneg (fmul, x, y))), z)
|
||||
// -> (fma (fneg x), y, (fneg z))
|
||||
if (N0.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FNEG) {
|
||||
SDValue N000 = N00.getOperand(0);
|
||||
if (N000.getOpcode() == ISD::FMUL) {
|
||||
return DAG.getNode(ISD::FMA, dl, VT,
|
||||
DAG.getNode(ISD::FNEG, dl, VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N000.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N000.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, dl, VT, N1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fold (fsub (fneg (fpext (fmul, x, y))), z)
|
||||
// -> (fma (fneg x), y, (fneg z))
|
||||
if (N0.getOpcode() == ISD::FNEG) {
|
||||
SDValue N00 = N0.getOperand(0);
|
||||
if (N00.getOpcode() == ISD::FP_EXTEND) {
|
||||
SDValue N000 = N00.getOperand(0);
|
||||
if (N000.getOpcode() == ISD::FMUL) {
|
||||
return DAG.getNode(ISD::FMA, dl, VT,
|
||||
DAG.getNode(ISD::FNEG, dl, VT,
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
|
||||
VT, N000.getOperand(0))),
|
||||
DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT,
|
||||
N000.getOperand(1)),
|
||||
DAG.getNode(ISD::FNEG, dl, VT, N1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9817,6 +9817,11 @@ bool PPCTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
|
||||
return TargetLowering::isZExtFree(Val, VT2);
|
||||
}
|
||||
|
||||
bool PPCTargetLowering::isFPExtFree(EVT VT) const {
|
||||
assert(VT.isFloatingPoint());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
|
||||
return isInt<16>(Imm) || isUInt<16>(Imm);
|
||||
}
|
||||
|
@ -528,6 +528,8 @@ namespace llvm {
|
||||
|
||||
bool isZExtFree(SDValue Val, EVT VT2) const override;
|
||||
|
||||
bool isFPExtFree(EVT VT) const override;
|
||||
|
||||
/// \brief Returns true if it is beneficial to convert a load of a constant
|
||||
/// to just the constant itself.
|
||||
bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
|
||||
|
Loading…
x
Reference in New Issue
Block a user