diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-04-24 22:28:58 +0000 | 
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-04-24 22:28:58 +0000 | 
| commit | 6f41bf948b5f34aec8f03ec0fbb1f6eabea26984 (patch) | |
| tree | 28e3e6a9603d78b2e2f366f01385f0eb0ce5d78f /llvm/lib | |
| parent | 8372b467f18da0ff92ff59ba878365e8f4790212 (diff) | |
| download | bcm5719-llvm-6f41bf948b5f34aec8f03ec0fbb1f6eabea26984.tar.gz bcm5719-llvm-6f41bf948b5f34aec8f03ec0fbb1f6eabea26984.zip  | |
[DAGCombiner] scale repeated FP divisor by splat factor
If we have a vector FP division with a splatted divisor, use the existing transform
that converts 'x/y' into 'x * (1.0/y)' to allow more conversions. This can then
potentially be converted into a scalar FP division by existing combines (rL358984)
as seen in the tests here.
That can be a potentially big perf difference if scalar fdiv has better timing
(including avoiding possible frequency throttling for vector ops).
Differential Revision: https://reviews.llvm.org/D61028
llvm-svn: 359147
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 | 
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d1da7e39329..6d351cc57ac 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11901,6 +11901,9 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {  // FDIVs may be lower than the cost of one FDIV and two FMULs. Another reason  // is the critical path is increased from "one FDIV" to "one FDIV + one FMUL".  SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) { +  // TODO: Limit this transform based on optsize/minsize - it always creates at +  //       least 1 extra instruction. But the perf win may be substantial enough +  //       that only minsize should restrict this.    bool UnsafeMath = DAG.getTarget().Options.UnsafeFPMath;    const SDNodeFlags Flags = N->getFlags();    if (!UnsafeMath && !Flags.hasAllowReciprocal()) @@ -11916,7 +11919,15 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {    // possibly be enough uses of the divisor to make the transform worthwhile.    SDValue N1 = N->getOperand(1);    unsigned MinUses = TLI.combineRepeatedFPDivisors(); -  if (!MinUses || N1->use_size() < MinUses) + +  // For splat vectors, scale the number of uses by the splat factor. If we can +  // convert the division into a scalar op, that will likely be much faster. +  unsigned NumElts = 1; +  EVT VT = N->getValueType(0); +  if (VT.isVector() && DAG.isSplatValue(N1)) +    NumElts = VT.getVectorNumElements(); + +  if (!MinUses || (N1->use_size() * NumElts) < MinUses)      return SDValue();    // Find all FDIV users of the same divisor. @@ -11933,10 +11944,9 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {    // Now that we have the actual number of divisor uses, make sure it meets    // the minimum threshold specified by the target. -  if (Users.size() < MinUses) +  if ((Users.size() * NumElts) < MinUses)      return SDValue(); -  EVT VT = N->getValueType(0);    SDLoc DL(N);    SDValue FPOne = DAG.getConstantFP(1.0, DL, VT);    SDValue Reciprocal = DAG.getNode(ISD::FDIV, DL, VT, FPOne, N1, Flags);  | 

