diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp | 28 | 
1 files changed, 17 insertions, 11 deletions
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp index 4e899ae6668e..0d69441ebb7f 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp @@ -37,13 +37,13 @@ bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,      const MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); -    // Match non-equal FrameIndexes - a FrameIndex stemming from an -    // alloca will not have it's ObjectOffset set until post-DAG and -    // as such we must assume the two framesIndices are incomparable. +    // Match non-equal FrameIndexes - If both frame indices are fixed +    // we know their relative offsets and can compare them. Otherwise +    // we must be conservative.      if (auto *A = dyn_cast<FrameIndexSDNode>(Base))        if (auto *B = dyn_cast<FrameIndexSDNode>(Other.Base)) -        if (!MFI.getObjectAllocation(A->getIndex()) && -            !MFI.getObjectAllocation(B->getIndex())) { +        if (MFI.isFixedObjectIndex(A->getIndex()) && +            MFI.isFixedObjectIndex(B->getIndex())) {            Off += MFI.getObjectOffset(B->getIndex()) -                   MFI.getObjectOffset(A->getIndex());            return true; @@ -60,12 +60,18 @@ BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) {    int64_t Offset = 0;    bool IsIndexSignExt = false; -  // Consume constant adds -  while (Base->getOpcode() == ISD::ADD && -         isa<ConstantSDNode>(Base->getOperand(1))) { -    int64_t POffset = cast<ConstantSDNode>(Base->getOperand(1))->getSExtValue(); -    Offset += POffset; -    Base = Base->getOperand(0); +  // Consume constant adds & ors with appropriate masking. +  while (Base->getOpcode() == ISD::ADD || Base->getOpcode() == ISD::OR) { +    if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) { +      // Only consider ORs which act as adds. +      if (Base->getOpcode() == ISD::OR && +          !DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue())) +        break; +      Offset += C->getSExtValue(); +      Base = Base->getOperand(0); +      continue; +    } +    break;    }    if (Base->getOpcode() == ISD::ADD) {  | 
