@@ -1228,81 +1228,88 @@ bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
12281228 if (TII->areMemAccessesTriviallyDisjoint (*this , Other))
12291229 return false ;
12301230
1231- // FIXME: Need to handle multiple memory operands to support all targets.
1232- if (!hasOneMemOperand () || !Other.hasOneMemOperand ())
1231+ if (memoperands_empty () || Other.memoperands_empty ())
12331232 return true ;
12341233
1235- MachineMemOperand *MMOa = *memoperands_begin ();
1236- MachineMemOperand *MMOb = *Other.memoperands_begin ();
1237-
1238- // The following interface to AA is fashioned after DAGCombiner::isAlias
1239- // and operates with MachineMemOperand offset with some important
1240- // assumptions:
1241- // - LLVM fundamentally assumes flat address spaces.
1242- // - MachineOperand offset can *only* result from legalization and
1243- // cannot affect queries other than the trivial case of overlap
1244- // checking.
1245- // - These offsets never wrap and never step outside
1246- // of allocated objects.
1247- // - There should never be any negative offsets here.
1248- //
1249- // FIXME: Modify API to hide this math from "user"
1250- // Even before we go to AA we can reason locally about some
1251- // memory objects. It can save compile time, and possibly catch some
1252- // corner cases not currently covered.
1253-
1254- int64_t OffsetA = MMOa->getOffset ();
1255- int64_t OffsetB = MMOb->getOffset ();
1256- int64_t MinOffset = std::min (OffsetA, OffsetB);
1257-
1258- uint64_t WidthA = MMOa->getSize ();
1259- uint64_t WidthB = MMOb->getSize ();
1260- bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
1261- bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;
1262-
1263- const Value *ValA = MMOa->getValue ();
1264- const Value *ValB = MMOb->getValue ();
1265- bool SameVal = (ValA && ValB && (ValA == ValB));
1266- if (!SameVal) {
1267- const PseudoSourceValue *PSVa = MMOa->getPseudoValue ();
1268- const PseudoSourceValue *PSVb = MMOb->getPseudoValue ();
1269- if (PSVa && ValB && !PSVa->mayAlias (&MFI))
1270- return false ;
1271- if (PSVb && ValA && !PSVb->mayAlias (&MFI))
1272- return false ;
1273- if (PSVa && PSVb && (PSVa == PSVb))
1274- SameVal = true ;
1275- }
1234+ auto HasAlias = [&](const MachineMemOperand &MMOa,
1235+ const MachineMemOperand &MMOb) {
1236+ // The following interface to AA is fashioned after DAGCombiner::isAlias
1237+ // and operates with MachineMemOperand offset with some important
1238+ // assumptions:
1239+ // - LLVM fundamentally assumes flat address spaces.
1240+ // - MachineOperand offset can *only* result from legalization and
1241+ // cannot affect queries other than the trivial case of overlap
1242+ // checking.
1243+ // - These offsets never wrap and never step outside
1244+ // of allocated objects.
1245+ // - There should never be any negative offsets here.
1246+ //
1247+ // FIXME: Modify API to hide this math from "user"
1248+ // Even before we go to AA we can reason locally about some
1249+ // memory objects. It can save compile time, and possibly catch some
1250+ // corner cases not currently covered.
1251+
1252+ int64_t OffsetA = MMOa.getOffset ();
1253+ int64_t OffsetB = MMOb.getOffset ();
1254+ int64_t MinOffset = std::min (OffsetA, OffsetB);
1255+
1256+ uint64_t WidthA = MMOa.getSize ();
1257+ uint64_t WidthB = MMOb.getSize ();
1258+ bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
1259+ bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;
1260+
1261+ const Value *ValA = MMOa.getValue ();
1262+ const Value *ValB = MMOb.getValue ();
1263+ bool SameVal = (ValA && ValB && (ValA == ValB));
1264+ if (!SameVal) {
1265+ const PseudoSourceValue *PSVa = MMOa.getPseudoValue ();
1266+ const PseudoSourceValue *PSVb = MMOb.getPseudoValue ();
1267+ if (PSVa && ValB && !PSVa->mayAlias (&MFI))
1268+ return false ;
1269+ if (PSVb && ValA && !PSVb->mayAlias (&MFI))
1270+ return false ;
1271+ if (PSVa && PSVb && (PSVa == PSVb))
1272+ SameVal = true ;
1273+ }
1274+
1275+ if (SameVal) {
1276+ if (!KnownWidthA || !KnownWidthB)
1277+ return true ;
1278+ int64_t MaxOffset = std::max (OffsetA, OffsetB);
1279+ int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
1280+ return (MinOffset + LowWidth > MaxOffset);
1281+ }
12761282
1277- if (SameVal) {
1278- if (!KnownWidthA || !KnownWidthB)
1283+ if (!AA)
12791284 return true ;
1280- int64_t MaxOffset = std::max (OffsetA, OffsetB);
1281- int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
1282- return (MinOffset + LowWidth > MaxOffset);
1283- }
12841285
1285- if (!AA )
1286- return true ;
1286+ if (!ValA || !ValB )
1287+ return true ;
12871288
1288- if (!ValA || !ValB)
1289- return true ;
1289+ assert ((OffsetA >= 0 ) && " Negative MachineMemOperand offset " );
1290+ assert ((OffsetB >= 0 ) && " Negative MachineMemOperand offset " ) ;
12901291
1291- assert ((OffsetA >= 0 ) && " Negative MachineMemOperand offset" );
1292- assert ((OffsetB >= 0 ) && " Negative MachineMemOperand offset" );
1292+ int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset
1293+ : MemoryLocation::UnknownSize;
1294+ int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset
1295+ : MemoryLocation::UnknownSize;
12931296
1294- int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset
1295- : MemoryLocation::UnknownSize;
1296- int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset
1297- : MemoryLocation::UnknownSize;
1297+ AliasResult AAResult =
1298+ AA->alias (MemoryLocation (ValA, OverlapA,
1299+ UseTBAA ? MMOa.getAAInfo () : AAMDNodes ()),
1300+ MemoryLocation (ValB, OverlapB,
1301+ UseTBAA ? MMOb.getAAInfo () : AAMDNodes ()));
12981302
1299- AliasResult AAResult = AA->alias (
1300- MemoryLocation (ValA, OverlapA,
1301- UseTBAA ? MMOa->getAAInfo () : AAMDNodes ()),
1302- MemoryLocation (ValB, OverlapB,
1303- UseTBAA ? MMOb->getAAInfo () : AAMDNodes ()));
1303+ return (AAResult != NoAlias);
1304+ };
13041305
1305- return (AAResult != NoAlias);
1306+ for (auto &&MMOa : memoperands ()) {
1307+ for (auto &&MMOb : Other.memoperands ()) {
1308+ if (HasAlias (*MMOa, *MMOb))
1309+ return true ;
1310+ }
1311+ }
1312+ return false ;
13061313}
13071314
13081315// / hasOrderedMemoryRef - Return true if this instruction may have an ordered
0 commit comments