aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineInstr.cpp
diff options
context:
space:
mode:
authorJean-Michel Gorius <jean-michel.gorius@orange.fr>2020-05-21 16:30:48 +0200
committerJean-Michel Gorius <jean-michel.gorius@orange.fr>2020-05-21 23:02:54 +0200
commit7019cea26dfef5882c96f278c32d0f9c49a5e516 (patch)
treeb863c0a4914a03946e34059410f9bd2c06b3efc7 /llvm/lib/CodeGen/MachineInstr.cpp
parent689e616ed0b1210517dda65dc3528f8fdb9a5959 (diff)
downloadllvm-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.cpp137
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