diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h index fdb262c4bbe..4a28f1966b7 100644 --- a/include/llvm/CodeGen/TargetLowering.h +++ b/include/llvm/CodeGen/TargetLowering.h @@ -255,6 +255,13 @@ public: // or custom. }; + /// Enum that specifies when a float negation is beneficial. + enum class NegatibleCost { + Expensive = 0, // Negated expression is more expensive. + Neutral = 1, // Negated expression has the same cost. + Cheaper = 2 // Negated expression is cheaper. + }; + class ArgListEntry { public: Value *Val = nullptr; @@ -3485,14 +3492,14 @@ public: llvm_unreachable("Not Implemented"); } - /// Return 1 if we can compute the negated form of the specified expression - /// for the same cost as the expression itself, or 2 if we can compute the - /// negated form more cheaply than the expression itself. Else return 0. - virtual char isNegatibleForFree(SDValue Op, SelectionDAG &DAG, - bool LegalOperations, bool ForCodeSize, - unsigned Depth = 0) const; + /// Returns whether computing the negated form of the specified expression is + /// more expensive, the same cost or cheaper. + virtual NegatibleCost getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth = 0) const; - /// If isNegatibleForFree returns true, return the newly negated expression. + /// If getNegatibleCost returns Neutral/Cheaper, return the newly negated + /// expression. virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize, unsigned Depth = 0) const; diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 644307e3aa6..b840fd4a048 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12165,14 +12165,16 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { // fold (fadd A, (fneg B)) -> (fsub A, B) if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT)) && - TLI.isNegatibleForFree(N1, DAG, LegalOperations, ForCodeSize) == 2) + TLI.getNegatibleCost(N1, DAG, LegalOperations, ForCodeSize) == + TargetLowering::NegatibleCost::Cheaper) return DAG.getNode( ISD::FSUB, DL, VT, N0, TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize), Flags); // fold (fadd (fneg A), B) -> (fsub B, A) if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT)) && - TLI.isNegatibleForFree(N0, DAG, LegalOperations, ForCodeSize) == 2) + TLI.getNegatibleCost(N0, DAG, LegalOperations, ForCodeSize) == + TargetLowering::NegatibleCost::Cheaper) return DAG.getNode( ISD::FSUB, DL, VT, N1, TLI.getNegatedExpression(N0, DAG, LegalOperations, ForCodeSize), Flags); @@ -12354,7 +12356,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { if (N0CFP && N0CFP->isZero()) { if (N0CFP->isNegative() || (Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros())) { - if (TLI.isNegatibleForFree(N1, DAG, LegalOperations, ForCodeSize)) + if (TLI.getNegatibleCost(N1, DAG, LegalOperations, ForCodeSize) != + TargetLowering::NegatibleCost::Expensive) return TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize); if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) return DAG.getNode(ISD::FNEG, DL, VT, N1, Flags); @@ -12373,7 +12376,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { } // fold (fsub A, (fneg B)) -> (fadd A, B) - if (TLI.isNegatibleForFree(N1, DAG, LegalOperations, ForCodeSize)) + if (TLI.getNegatibleCost(N1, DAG, LegalOperations, ForCodeSize) != + TargetLowering::NegatibleCost::Expensive) return DAG.getNode( ISD::FADD, DL, VT, N0, TLI.getNegatedExpression(N1, DAG, LegalOperations, ForCodeSize), Flags); @@ -12390,16 +12394,20 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { /// Return true if both inputs are at least as cheap in negated form and at /// least one input is strictly cheaper in negated form. bool DAGCombiner::isCheaperToUseNegatedFPOps(SDValue X, SDValue Y) { - if (char LHSNeg = - TLI.isNegatibleForFree(X, DAG, LegalOperations, ForCodeSize)) - if (char RHSNeg = - TLI.isNegatibleForFree(Y, DAG, LegalOperations, ForCodeSize)) - // Both negated operands are at least as cheap as their counterparts. - // Check to see if at least one is cheaper negated. - if (LHSNeg == 2 || RHSNeg == 2) - return true; + TargetLowering::NegatibleCost LHSNeg = + TLI.getNegatibleCost(X, DAG, LegalOperations, ForCodeSize); + if (TargetLowering::NegatibleCost::Expensive == LHSNeg) + return false; - return false; + TargetLowering::NegatibleCost RHSNeg = + TLI.getNegatibleCost(Y, DAG, LegalOperations, ForCodeSize); + if (TargetLowering::NegatibleCost::Expensive == RHSNeg) + return false; + + // Both negated operands are at least as cheap as their counterparts. + // Check to see if at least one is cheaper negated. + return (TargetLowering::NegatibleCost::Cheaper == LHSNeg || + TargetLowering::NegatibleCost::Cheaper == RHSNeg); } SDValue DAGCombiner::visitFMUL(SDNode *N) { @@ -12651,8 +12659,8 @@ SDValue DAGCombiner::visitFMA(SDNode *N) { // fold ((fma (fneg X), Y, (fneg Z)) -> fneg (fma X, Y, Z)) // fold ((fma X, (fneg Y), (fneg Z)) -> fneg (fma X, Y, Z)) if (!TLI.isFNegFree(VT) && - TLI.isNegatibleForFree(SDValue(N, 0), DAG, LegalOperations, - ForCodeSize) == 2) + TLI.getNegatibleCost(SDValue(N, 0), DAG, LegalOperations, ForCodeSize) == + TargetLowering::NegatibleCost::Cheaper) return DAG.getNode(ISD::FNEG, DL, VT, TLI.getNegatedExpression(SDValue(N, 0), DAG, LegalOperations, ForCodeSize), @@ -13387,11 +13395,12 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { if (isConstantFPBuildVectorOrConstantFP(N0)) return DAG.getNode(ISD::FNEG, SDLoc(N), VT, N0); - if (TLI.isNegatibleForFree(N0, DAG, LegalOperations, ForCodeSize)) + if (TLI.getNegatibleCost(N0, DAG, LegalOperations, ForCodeSize) != + TargetLowering::NegatibleCost::Expensive) return TLI.getNegatedExpression(N0, DAG, LegalOperations, ForCodeSize); // -(X-Y) -> (Y-X) is unsafe because when X==Y, -0.0 != +0.0 FIXME: This is - // duplicated in isNegatibleForFree, but isNegatibleForFree doesn't know it + // duplicated in getNegatibleCost, but getNegatibleCost doesn't know it // was called from a context with a nsz flag if the input fsub does not. if (N0.getOpcode() == ISD::FSUB && (DAG.getTarget().Options.NoSignedZerosFPMath || diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index b7ce7fa16b2..f41bdf09929 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5545,12 +5545,13 @@ verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const { return false; } -char TargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG, - bool LegalOperations, bool ForCodeSize, - unsigned Depth) const { +TargetLowering::NegatibleCost +TargetLowering::getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth) const { // fneg is removable even if it has multiple uses. if (Op.getOpcode() == ISD::FNEG) - return 2; + return NegatibleCost::Cheaper; // Don't allow anything with multiple uses unless we know it is free. EVT VT = Op.getValueType(); @@ -5558,107 +5559,115 @@ char TargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG, const TargetOptions &Options = DAG.getTarget().Options; if (!Op.hasOneUse() && !(Op.getOpcode() == ISD::FP_EXTEND && isFPExtFree(VT, Op.getOperand(0).getValueType()))) - return 0; + return NegatibleCost::Expensive; // Don't recurse exponentially. if (Depth > SelectionDAG::MaxRecursionDepth) - return 0; + return NegatibleCost::Expensive; switch (Op.getOpcode()) { case ISD::ConstantFP: { if (!LegalOperations) - return 1; + return NegatibleCost::Neutral; // Don't invert constant FP values after legalization unless the target says // the negated constant is legal. - return isOperationLegal(ISD::ConstantFP, VT) || - isFPImmLegal(neg(cast(Op)->getValueAPF()), VT, - ForCodeSize); + if (isOperationLegal(ISD::ConstantFP, VT) || + isFPImmLegal(neg(cast(Op)->getValueAPF()), VT, + ForCodeSize)) + return NegatibleCost::Neutral; + break; } case ISD::BUILD_VECTOR: { // Only permit BUILD_VECTOR of constants. if (llvm::any_of(Op->op_values(), [&](SDValue N) { return !N.isUndef() && !isa(N); })) - return 0; + return NegatibleCost::Expensive; if (!LegalOperations) - return 1; + return NegatibleCost::Neutral; if (isOperationLegal(ISD::ConstantFP, VT) && isOperationLegal(ISD::BUILD_VECTOR, VT)) - return 1; - return llvm::all_of(Op->op_values(), [&](SDValue N) { - return N.isUndef() || - isFPImmLegal(neg(cast(N)->getValueAPF()), VT, - ForCodeSize); - }); + return NegatibleCost::Neutral; + if (llvm::all_of(Op->op_values(), [&](SDValue N) { + return N.isUndef() || + isFPImmLegal(neg(cast(N)->getValueAPF()), VT, + ForCodeSize); + })) + return NegatibleCost::Neutral; + break; } - case ISD::FADD: + case ISD::FADD: { if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros()) - return 0; + return NegatibleCost::Expensive; // After operation legalization, it might not be legal to create new FSUBs. if (LegalOperations && !isOperationLegalOrCustom(ISD::FSUB, VT)) - return 0; + return NegatibleCost::Expensive; // fold (fneg (fadd A, B)) -> (fsub (fneg A), B) - if (char V = isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1)) - return V; + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V0 != NegatibleCost::Expensive) + return V0; // fold (fneg (fadd A, B)) -> (fsub (fneg B), A) - return isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations, - ForCodeSize, Depth + 1); + return getNegatibleCost(Op.getOperand(1), DAG, LegalOperations, ForCodeSize, + Depth + 1); + } case ISD::FSUB: // We can't turn -(A-B) into B-A when we honor signed zeros. if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros()) - return 0; + return NegatibleCost::Expensive; // fold (fneg (fsub A, B)) -> (fsub B, A) - return 1; - + return NegatibleCost::Neutral; case ISD::FMUL: - case ISD::FDIV: + case ISD::FDIV: { // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y) or (fmul X, (fneg Y)) - if (char V = isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1)) - return V; + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V0 != NegatibleCost::Expensive) + return V0; // Ignore X * 2.0 because that is expected to be canonicalized to X + X. if (auto *C = isConstOrConstSplatFP(Op.getOperand(1))) if (C->isExactlyValue(2.0) && Op.getOpcode() == ISD::FMUL) - return 0; - - return isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations, - ForCodeSize, Depth + 1); + return NegatibleCost::Expensive; + return getNegatibleCost(Op.getOperand(1), DAG, LegalOperations, ForCodeSize, + Depth + 1); + } case ISD::FMA: case ISD::FMAD: { if (!Options.NoSignedZerosFPMath && !Flags.hasNoSignedZeros()) - return 0; + return NegatibleCost::Expensive; // fold (fneg (fma X, Y, Z)) -> (fma (fneg X), Y, (fneg Z)) // fold (fneg (fma X, Y, Z)) -> (fma X, (fneg Y), (fneg Z)) - char V2 = isNegatibleForFree(Op.getOperand(2), DAG, LegalOperations, - ForCodeSize, Depth + 1); - if (!V2) - return 0; + NegatibleCost V2 = getNegatibleCost(Op.getOperand(2), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (NegatibleCost::Expensive == V2) + return NegatibleCost::Expensive; // One of Op0/Op1 must be cheaply negatible, then select the cheapest. - char V0 = isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1); - char V1 = isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations, - ForCodeSize, Depth + 1); - char V01 = std::max(V0, V1); - return V01 ? std::max(V01, V2) : 0; + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + NegatibleCost V1 = getNegatibleCost(Op.getOperand(1), DAG, LegalOperations, + ForCodeSize, Depth + 1); + NegatibleCost V01 = std::max(V0, V1); + if (V01 == NegatibleCost::Expensive) + return NegatibleCost::Expensive; + return std::max(V01, V2); } case ISD::FP_EXTEND: case ISD::FP_ROUND: case ISD::FSIN: - return isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1); + return getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, + Depth + 1); } - return 0; + return NegatibleCost::Expensive; } SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, @@ -5670,7 +5679,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, return Op.getOperand(0); assert(Depth <= SelectionDAG::MaxRecursionDepth && - "getNegatedExpression doesn't match isNegatibleForFree"); + "getNegatedExpression doesn't match getNegatibleCost"); const SDNodeFlags Flags = Op->getFlags(); switch (Op.getOpcode()) { @@ -5692,14 +5701,15 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, } return DAG.getBuildVector(Op.getValueType(), SDLoc(Op), Ops); } - case ISD::FADD: + case ISD::FADD: { assert((DAG.getTarget().Options.NoSignedZerosFPMath || Flags.hasNoSignedZeros()) && "Expected NSZ fp-flag"); // fold (fneg (fadd A, B)) -> (fsub (fneg A), B) - if (isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, - Depth + 1)) + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V0 != NegatibleCost::Expensive) return DAG.getNode(ISD::FSUB, SDLoc(Op), Op.getValueType(), getNegatedExpression(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, @@ -5711,6 +5721,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, LegalOperations, ForCodeSize, Depth + 1), Op.getOperand(0), Flags); + } case ISD::FSUB: // fold (fneg (fsub 0, B)) -> B if (ConstantFPSDNode *N0CFP = @@ -5723,10 +5734,11 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, Op.getOperand(1), Op.getOperand(0), Flags); case ISD::FMUL: - case ISD::FDIV: + case ISD::FDIV: { // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y) - if (isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, - Depth + 1)) + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V0 != NegatibleCost::Expensive) return DAG.getNode(Op.getOpcode(), SDLoc(Op), Op.getValueType(), getNegatedExpression(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, @@ -5739,7 +5751,7 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, getNegatedExpression(Op.getOperand(1), DAG, LegalOperations, ForCodeSize, Depth + 1), Flags); - + } case ISD::FMA: case ISD::FMAD: { assert((DAG.getTarget().Options.NoSignedZerosFPMath || @@ -5749,12 +5761,12 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, SDValue Neg2 = getNegatedExpression(Op.getOperand(2), DAG, LegalOperations, ForCodeSize, Depth + 1); - char V0 = isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1); - char V1 = isNegatibleForFree(Op.getOperand(1), DAG, LegalOperations, - ForCodeSize, Depth + 1); + NegatibleCost V0 = getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, + ForCodeSize, Depth + 1); + NegatibleCost V1 = getNegatibleCost(Op.getOperand(1), DAG, LegalOperations, + ForCodeSize, Depth + 1); // TODO: This is a hack. It is possible that costs have changed between now - // and the initial calls to isNegatibleForFree(). That is because we + // and the initial calls to getNegatibleCost(). That is because we // are rewriting the expression, and that may change the number of // uses (and therefore the cost) of values. If the negation costs are // equal, only negate this value if it is a constant. Otherwise, try diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index 24e0b9a6d02..bbd5c8ef1eb 100644 --- a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -733,24 +733,24 @@ bool AMDGPUTargetLowering::isSDNodeAlwaysUniform(const SDNode * N) const { } } -char AMDGPUTargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG, - bool LegalOperations, - bool ForCodeSize, - unsigned Depth) const { +TargetLowering::NegatibleCost +AMDGPUTargetLowering::getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth) const { switch (Op.getOpcode()) { - case ISD::FMA: - case ISD::FMAD: { - // Negating a fma is not free if it has users without source mods. - if (!allUsesHaveSourceMods(Op.getNode())) - return 0; - break; - } - default: - break; + case ISD::FMA: + case ISD::FMAD: { + // Negating a fma is not free if it has users without source mods. + if (!allUsesHaveSourceMods(Op.getNode())) + return NegatibleCost::Expensive; + break; + } + default: + break; } - return TargetLowering::isNegatibleForFree(Op, DAG, LegalOperations, - ForCodeSize, Depth); + return TargetLowering::getNegatibleCost(Op, DAG, LegalOperations, ForCodeSize, + Depth); } //===---------------------------------------------------------------------===// diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.h b/lib/Target/AMDGPU/AMDGPUISelLowering.h index f8af41b8d93..ffe511394c7 100644 --- a/lib/Target/AMDGPU/AMDGPUISelLowering.h +++ b/lib/Target/AMDGPU/AMDGPUISelLowering.h @@ -172,8 +172,9 @@ public: bool isZExtFree(EVT Src, EVT Dest) const override; bool isZExtFree(SDValue Val, EVT VT2) const override; - char isNegatibleForFree(SDValue Op, SelectionDAG &DAG, bool LegalOperations, - bool ForCodeSize, unsigned Depth) const override; + NegatibleCost getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth) const override; bool isNarrowingProfitable(EVT VT1, EVT VT2) const override; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8cd177aa302..565ca672716 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -43217,17 +43217,17 @@ static SDValue combineFneg(SDNode *N, SelectionDAG &DAG, return SDValue(); } -char X86TargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG, - bool LegalOperations, - bool ForCodeSize, - unsigned Depth) const { +TargetLowering::NegatibleCost +X86TargetLowering::getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth) const { // fneg patterns are removable even if they have multiple uses. if (isFNEG(DAG, Op.getNode(), Depth)) - return 2; + return NegatibleCost::Cheaper; // Don't recurse exponentially. if (Depth > SelectionDAG::MaxRecursionDepth) - return 0; + return NegatibleCost::Expensive; EVT VT = Op.getValueType(); EVT SVT = VT.getScalarType(); @@ -43248,20 +43248,20 @@ char X86TargetLowering::isNegatibleForFree(SDValue Op, SelectionDAG &DAG, // This is always negatible for free but we might be able to remove some // extra operand negations as well. for (int i = 0; i != 3; ++i) { - char V = isNegatibleForFree(Op.getOperand(i), DAG, LegalOperations, - ForCodeSize, Depth + 1); - if (V == 2) + NegatibleCost V = getNegatibleCost(Op.getOperand(i), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V == NegatibleCost::Cheaper) return V; } - return 1; + return NegatibleCost::Neutral; } case X86ISD::FRCP: - return isNegatibleForFree(Op.getOperand(0), DAG, LegalOperations, - ForCodeSize, Depth + 1); + return getNegatibleCost(Op.getOperand(0), DAG, LegalOperations, ForCodeSize, + Depth + 1); } - return TargetLowering::isNegatibleForFree(Op, DAG, LegalOperations, - ForCodeSize, Depth); + return TargetLowering::getNegatibleCost(Op, DAG, LegalOperations, ForCodeSize, + Depth); } SDValue X86TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, @@ -43293,9 +43293,9 @@ SDValue X86TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // extra operand negations as well. SmallVector NewOps(Op.getNumOperands(), SDValue()); for (int i = 0; i != 3; ++i) { - char V = isNegatibleForFree(Op.getOperand(i), DAG, LegalOperations, - ForCodeSize, Depth + 1); - if (V == 2) + NegatibleCost V = getNegatibleCost(Op.getOperand(i), DAG, LegalOperations, + ForCodeSize, Depth + 1); + if (V == NegatibleCost::Cheaper) NewOps[i] = getNegatedExpression(Op.getOperand(i), DAG, LegalOperations, ForCodeSize, Depth + 1); } @@ -44154,7 +44154,8 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG, auto invertIfNegative = [&DAG, &TLI, &DCI](SDValue &V) { bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize(); bool LegalOperations = !DCI.isBeforeLegalizeOps(); - if (TLI.isNegatibleForFree(V, DAG, LegalOperations, CodeSize) == 2) { + if (TLI.getNegatibleCost(V, DAG, LegalOperations, CodeSize) == + TargetLowering::NegatibleCost::Cheaper) { V = TLI.getNegatedExpression(V, DAG, LegalOperations, CodeSize); return true; } @@ -44163,7 +44164,8 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG, if (V.getOpcode() == ISD::EXTRACT_VECTOR_ELT && isNullConstant(V.getOperand(1))) { SDValue Vec = V.getOperand(0); - if (TLI.isNegatibleForFree(Vec, DAG, LegalOperations, CodeSize) == 2) { + if (TLI.getNegatibleCost(Vec, DAG, LegalOperations, CodeSize) == + TargetLowering::NegatibleCost::Cheaper) { SDValue NegVal = TLI.getNegatedExpression(Vec, DAG, LegalOperations, CodeSize); V = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), V.getValueType(), @@ -44209,7 +44211,8 @@ static SDValue combineFMADDSUB(SDNode *N, SelectionDAG &DAG, bool LegalOperations = !DCI.isBeforeLegalizeOps(); SDValue N2 = N->getOperand(2); - if (TLI.isNegatibleForFree(N2, DAG, LegalOperations, CodeSize) != 2) + if (TLI.getNegatibleCost(N2, DAG, LegalOperations, CodeSize) != + TargetLowering::NegatibleCost::Cheaper) return SDValue(); SDValue NegN2 = TLI.getNegatedExpression(N2, DAG, LegalOperations, CodeSize); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 8c085c7f77f..e27fbaed588 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -808,13 +808,14 @@ namespace llvm { /// and some i16 instructions are slow. bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const override; - /// Return 1 if we can compute the negated form of the specified expression - /// for the same cost as the expression itself, or 2 if we can compute the - /// negated form more cheaply than the expression itself. Else return 0. - char isNegatibleForFree(SDValue Op, SelectionDAG &DAG, bool LegalOperations, - bool ForCodeSize, unsigned Depth) const override; + /// Returns whether computing the negated form of the specified expression + /// is more expensive, the same cost or cheaper. + NegatibleCost getNegatibleCost(SDValue Op, SelectionDAG &DAG, + bool LegalOperations, bool ForCodeSize, + unsigned Depth) const override; - /// If isNegatibleForFree returns true, return the newly negated expression. + /// If getNegatibleCost returns Neutral/Cheaper, return the newly negated + /// expression. SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOperations, bool ForCodeSize, unsigned Depth) const override;