diff options
Diffstat (limited to 'llvm/lib/Target/X86')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 31 | 
1 files changed, 31 insertions, 0 deletions
| diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 95d31e62caf..fcf9b4148b4 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2464,6 +2464,37 @@ bool X86DAGToDAGISel::selectLEAAddr(SDValue N,        Complexity += 2;    } +  // Heuristic: try harder to form an LEA from ADD if the operands set flags. +  // Unlike ADD, LEA does not affect flags, so we will be less likely to require +  // duplicating flag-producing instructions later in the pipeline. +  if (N.getOpcode() == ISD::ADD) { +    auto isMathWithFlags = [](SDValue V) { +      switch (V.getOpcode()) { +      case X86ISD::ADD: +      case X86ISD::SUB: +      case X86ISD::ADC: +      case X86ISD::SBB: +      /* TODO: These opcodes can be added safely, but we may want to justify +               their inclusion for different reasons (better for reg-alloc). +      case X86ISD::SMUL: +      case X86ISD::UMUL: +      case X86ISD::OR: +      case X86ISD::XOR: +      case X86ISD::AND: +      */ +        // Value 1 is the flag output of the node - verify it's not dead. +        return !SDValue(V.getNode(), 1).use_empty(); +      default: +        return false; +      } +    }; +    // TODO: This could be an 'or' rather than 'and' to make the transform more +    //       likely to happen. We might want to factor in whether there's a +    //       load folding opportunity for the math op that disappears with LEA. +    if (isMathWithFlags(N.getOperand(0)) && isMathWithFlags(N.getOperand(1))) +      Complexity++; +  } +    if (AM.Disp)      Complexity++; | 

