Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -1170,6 +1170,12 @@ assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs"); } + /// clearMemRefs - Clear this MachineInstr's memory reference descriptor list. + void clearMemRefs() { + MemRefs = nullptr; + NumMemRefs = 0; + } + private: /// getRegInfo - If this instruction is embedded into a MachineFunction, /// return the MachineRegisterInfo object for the current function, otherwise Index: lib/CodeGen/BranchFolding.cpp =================================================================== --- lib/CodeGen/BranchFolding.cpp +++ lib/CodeGen/BranchFolding.cpp @@ -24,6 +24,7 @@ #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" @@ -728,6 +729,42 @@ return true; } +static bool hasIdentialMMOs(const MachineInstr *MI1, + const MachineInstr *MI2) { + MachineInstr::mmo_iterator I1 = MI1->memoperands_begin(), + E1 = MI1->memoperands_end(); + MachineInstr::mmo_iterator I2 = MI2->memoperands_begin(), + E2 = MI2->memoperands_end(); + + if ((E1 - I1) != (E2 - I2)) + return false; + + for (; I1 != E1; ++I1, ++I2) { + const Value *V1 = (*I1)->getValue(); + const Value *V2 = (*I2)->getValue(); + if (!V1 || !V2 || (V1 != V2)) + return false; + } + + return true; +} + +static void removeMMOsFromMemoryOperations( + MachineBasicBlock &MBB, + MachineBasicBlock &MBBCommon) { + // Remove MMOs from memory operations in the common block + // when they do not match the ones from the block being tail-merged. + // This ensures later passes conservatively compute dependencies. + for (auto &MIICommon : MBBCommon) + if (MIICommon.mayLoad() || MIICommon.mayStore()) + for (auto &MII : MBB) + if (MII.mayLoad() || MII.mayStore()) + if (!hasIdentialMMOs(&MII, &MIICommon)) { + MIICommon.clearMemRefs(); + break; + } +} + // See if any of the blocks in MergePotentials (which all have a common single // successor, or all have no successor) can be tail-merged. If there is a // successor, any blocks in MergePotentials that are not tail-merged and @@ -841,6 +878,10 @@ continue; DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber() << (i == e-1 ? "" : ", ")); + + // Remove MMOs from memory operations as needed. + removeMMOsFromMemoryOperations(*SameTails[i].getBlock(), *MBB); + // Hack the end off BB i, making it jump to BB commonTailIndex instead. ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB); // BB i is no longer a predecessor of SuccBB; remove it from the worklist.