diff options
author | Jean-Michel Gorius <jean-michel.gorius@orange.fr> | 2020-05-21 16:30:48 +0200 |
---|---|---|
committer | Jean-Michel Gorius <jean-michel.gorius@orange.fr> | 2020-05-21 23:02:54 +0200 |
commit | 7019cea26dfef5882c96f278c32d0f9c49a5e516 (patch) | |
tree | b863c0a4914a03946e34059410f9bd2c06b3efc7 /llvm/lib/CodeGen/MachineInstr.cpp | |
parent | 689e616ed0b1210517dda65dc3528f8fdb9a5959 (diff) | |
download | llvm-7019cea26dfef5882c96f278c32d0f9c49a5e516.zip llvm-7019cea26dfef5882c96f278c32d0f9c49a5e516.tar.gz llvm-7019cea26dfef5882c96f278c32d0f9c49a5e516.tar.bz2 |
[CodeGen] Add support for multiple memory operands in MachineInstr::mayAlias
Summary:
To support all targets, the mayAlias member function needs to support instructions with multiple operands.
This revision also changes the order of the emitted instructions in some test cases.
Reviewers: efriedma, hfinkel, craig.topper, dmgreen
Reviewed By: efriedma
Subscribers: MatzeB, dmgreen, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D80161
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineInstr.cpp | 137 |
1 files changed, 72 insertions, 65 deletions
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 7afa61f..67c2438 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -1228,81 +1228,88 @@ bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other, if (TII->areMemAccessesTriviallyDisjoint(*this, Other)) return false; - // FIXME: Need to handle multiple memory operands to support all targets. - if (!hasOneMemOperand() || !Other.hasOneMemOperand()) + if (memoperands_empty() || Other.memoperands_empty()) return true; - MachineMemOperand *MMOa = *memoperands_begin(); - MachineMemOperand *MMOb = *Other.memoperands_begin(); - - // The following interface to AA is fashioned after DAGCombiner::isAlias - // and operates with MachineMemOperand offset with some important - // assumptions: - // - LLVM fundamentally assumes flat address spaces. - // - MachineOperand offset can *only* result from legalization and - // cannot affect queries other than the trivial case of overlap - // checking. - // - These offsets never wrap and never step outside - // of allocated objects. - // - There should never be any negative offsets here. - // - // FIXME: Modify API to hide this math from "user" - // Even before we go to AA we can reason locally about some - // memory objects. It can save compile time, and possibly catch some - // corner cases not currently covered. - - int64_t OffsetA = MMOa->getOffset(); - int64_t OffsetB = MMOb->getOffset(); - int64_t MinOffset = std::min(OffsetA, OffsetB); - - uint64_t WidthA = MMOa->getSize(); - uint64_t WidthB = MMOb->getSize(); - bool KnownWidthA = WidthA != MemoryLocation::UnknownSize; - bool KnownWidthB = WidthB != MemoryLocation::UnknownSize; - - const Value *ValA = MMOa->getValue(); - const Value *ValB = MMOb->getValue(); - bool SameVal = (ValA && ValB && (ValA == ValB)); - if (!SameVal) { - const PseudoSourceValue *PSVa = MMOa->getPseudoValue(); - const PseudoSourceValue *PSVb = MMOb->getPseudoValue(); - if (PSVa && ValB && !PSVa->mayAlias(&MFI)) - return false; - if (PSVb && ValA && !PSVb->mayAlias(&MFI)) - return false; - if (PSVa && PSVb && (PSVa == PSVb)) - SameVal = true; - } + auto HasAlias = [&](const MachineMemOperand &MMOa, + const MachineMemOperand &MMOb) { + // The following interface to AA is fashioned after DAGCombiner::isAlias + // and operates with MachineMemOperand offset with some important + // assumptions: + // - LLVM fundamentally assumes flat address spaces. + // - MachineOperand offset can *only* result from legalization and + // cannot affect queries other than the trivial case of overlap + // checking. + // - These offsets never wrap and never step outside + // of allocated objects. + // - There should never be any negative offsets here. + // + // FIXME: Modify API to hide this math from "user" + // Even before we go to AA we can reason locally about some + // memory objects. It can save compile time, and possibly catch some + // corner cases not currently covered. + + int64_t OffsetA = MMOa.getOffset(); + int64_t OffsetB = MMOb.getOffset(); + int64_t MinOffset = std::min(OffsetA, OffsetB); + + uint64_t WidthA = MMOa.getSize(); + uint64_t WidthB = MMOb.getSize(); + bool KnownWidthA = WidthA != MemoryLocation::UnknownSize; + bool KnownWidthB = WidthB != MemoryLocation::UnknownSize; + + const Value *ValA = MMOa.getValue(); + const Value *ValB = MMOb.getValue(); + bool SameVal = (ValA && ValB && (ValA == ValB)); + if (!SameVal) { + const PseudoSourceValue *PSVa = MMOa.getPseudoValue(); + const PseudoSourceValue *PSVb = MMOb.getPseudoValue(); + if (PSVa && ValB && !PSVa->mayAlias(&MFI)) + return false; + if (PSVb && ValA && !PSVb->mayAlias(&MFI)) + return false; + if (PSVa && PSVb && (PSVa == PSVb)) + SameVal = true; + } + + if (SameVal) { + if (!KnownWidthA || !KnownWidthB) + return true; + int64_t MaxOffset = std::max(OffsetA, OffsetB); + int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB; + return (MinOffset + LowWidth > MaxOffset); + } - if (SameVal) { - if (!KnownWidthA || !KnownWidthB) + if (!AA) return true; - int64_t MaxOffset = std::max(OffsetA, OffsetB); - int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB; - return (MinOffset + LowWidth > MaxOffset); - } - if (!AA) - return true; + if (!ValA || !ValB) + return true; - if (!ValA || !ValB) - return true; + assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); + assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); - assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); - assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); + int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset + : MemoryLocation::UnknownSize; + int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset + : MemoryLocation::UnknownSize; - int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset - : MemoryLocation::UnknownSize; - int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset - : MemoryLocation::UnknownSize; + AliasResult AAResult = + AA->alias(MemoryLocation(ValA, OverlapA, + UseTBAA ? MMOa.getAAInfo() : AAMDNodes()), + MemoryLocation(ValB, OverlapB, + UseTBAA ? MMOb.getAAInfo() : AAMDNodes())); - AliasResult AAResult = AA->alias( - MemoryLocation(ValA, OverlapA, - UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), - MemoryLocation(ValB, OverlapB, - UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); + return (AAResult != NoAlias); + }; - return (AAResult != NoAlias); + for (auto &&MMOa : memoperands()) { + for (auto &&MMOb : Other.memoperands()) { + if (HasAlias(*MMOa, *MMOb)) + return true; + } + } + return false; } /// hasOrderedMemoryRef - Return true if this instruction may have an ordered |