Index: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp =================================================================== --- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp +++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -159,45 +159,48 @@ const MachineFrameInfo *MFI, UnderlyingObjectsVector &Objects, const DataLayout &DL) { - if (!MI->hasOneMemOperand() || - (!(*MI->memoperands_begin())->getValue() && - !(*MI->memoperands_begin())->getPseudoValue()) || - (*MI->memoperands_begin())->isVolatile()) - return; - - if (const PseudoSourceValue *PSV = - (*MI->memoperands_begin())->getPseudoValue()) { - // Function that contain tail calls don't have unique PseudoSourceValue - // objects. Two PseudoSourceValues might refer to the same or overlapping - // locations. The client code calling this function assumes this is not the - // case. So return a conservative answer of no known object. - if (MFI->hasTailCall()) + for (auto *MMO : MI->memoperands()) { + if (MMO->isVolatile()) { + Objects.clear(); return; - - // For now, ignore PseudoSourceValues which may alias LLVM IR values - // because the code that uses this function has no way to cope with - // such aliases. - if (!PSV->isAliased(MFI)) { - bool MayAlias = PSV->mayAlias(MFI); - Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias)); } - return; - } - const Value *V = (*MI->memoperands_begin())->getValue(); - if (!V) - return; + if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) { + // Function that contain tail calls don't have unique PseudoSourceValue + // objects. Two PseudoSourceValues might refer to the same or overlapping + // locations. The client code calling this function assumes this is not the + // case. So return a conservative answer of no known object. + if (MFI->hasTailCall()) { + Objects.clear(); + return; + } - SmallVector Objs; - getUnderlyingObjects(V, Objs, DL); + // For now, ignore PseudoSourceValues which may alias LLVM IR values + // because the code that uses this function has no way to cope with + // such aliases. + if (PSV->isAliased(MFI)) { + Objects.clear(); + return; + } - for (Value *V : Objs) { - if (!isIdentifiedObject(V)) { + bool MayAlias = PSV->mayAlias(MFI); + Objects.push_back(UnderlyingObjectsVector::value_type(PSV, MayAlias)); + } else if (const Value *V = MMO->getValue()) { + SmallVector Objs; + getUnderlyingObjects(V, Objs, DL); + + for (Value *V : Objs) { + if (!isIdentifiedObject(V)) { + Objects.clear(); + return; + } + + Objects.push_back(UnderlyingObjectsVector::value_type(V, true)); + } + } else { Objects.clear(); return; } - - Objects.push_back(UnderlyingObjectsVector::value_type(V, true)); } } @@ -1037,6 +1040,14 @@ // Add dependencies to previous stores and loads mapped to V. addChainDependencies(SU, stores_, V); addChainDependencies(SU, (ThisMayAlias ? Loads : NonAliasLoads), V); + } + // Update the store map after all chains have been added to avoid adding + // self-loop edge if multiple underlying objects are present. + for (auto &underlObj : Objs) { + ValueType V = underlObj.getPointer(); + bool ThisMayAlias = underlObj.getInt(); + + Value2SUsMap &stores_ = (ThisMayAlias ? Stores : NonAliasStores); // Map this store to V. stores_.insert(SU, V); Index: llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll +++ llvm/trunk/test/CodeGen/AArch64/arm64-misched-multimmo.ll @@ -0,0 +1,23 @@ +; REQUIRES: asserts +; RUN: llc < %s -mtriple=arm64-linux-gnu -mcpu=cortex-a57 -enable-misched=0 -debug-only=misched -o - 2>&1 > /dev/null | FileCheck %s + + +@G1 = common global [100 x i32] zeroinitializer, align 4 +@G2 = common global [100 x i32] zeroinitializer, align 4 + +; Check that no scheduling dependencies are created between the paired loads and the store during post-RA MI scheduling. +; +; CHECK-LABEL: # Machine code for function foo: Properties: , %W{{[0-9]+}} = LDPWi +; CHECK: Successors: +; CHECK-NOT: ch SU(4) +; CHECK: SU(3) +; CHECK: SU(4): STRWui %WZR, %X{{[0-9]+}} +define i32 @foo() { +entry: + %0 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 0), align 4 + %1 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 1), align 4 + store i32 0, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G1, i64 0, i64 0), align 4 + %add = add nsw i32 %1, %0 + ret i32 %add +}