diff --git a/llvm/include/llvm/Transforms/Scalar/GVN.h b/llvm/include/llvm/Transforms/Scalar/GVN.h index bc0f108ac8260..ef2521220b0a2 100644 --- a/llvm/include/llvm/Transforms/Scalar/GVN.h +++ b/llvm/include/llvm/Transforms/Scalar/GVN.h @@ -19,6 +19,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/PHITransAddr.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/PassManager.h" @@ -37,8 +38,10 @@ class AAResults; class AssumeInst; class AssumptionCache; class BasicBlock; +class BatchAAResults; class BranchInst; class CallInst; +class EarliestEscapeAnalysis; class ExtractValueInst; class Function; class FunctionPass; @@ -255,6 +258,7 @@ class GVNPass : public PassInfoMixin { OptimizationRemarkEmitter *ORE = nullptr; ImplicitControlFlowTracking *ICF = nullptr; LoopInfo *LI = nullptr; + AAResults *AA = nullptr; MemorySSAUpdater *MSSAU = nullptr; ValueTable VN; @@ -344,21 +348,91 @@ class GVNPass : public PassInfoMixin { // List of critical edges to be split between iterations. SmallVector, 4> ToSplit; + enum class DepKind { + Other = 0, // Unknown value. + Def, // Exactly overlapping locations. + Clobber, // Reaching value superset of needed bits. + }; + + // Describe a memory location value, such that there exists a path to a point + // in the program, along which that memory location is not modified. + struct ReachingMemVal { + DepKind Kind; + BasicBlock *Block; + const Value *Addr; + Instruction *Inst; + int32_t Offset; + + static ReachingMemVal getUnknown(BasicBlock *BB, const Value *Addr, + Instruction *Inst = nullptr) { + return {DepKind::Other, BB, Addr, Inst, -1}; + } + + static ReachingMemVal getDef(const Value *Addr, Instruction *Inst) { + return {DepKind::Def, Inst->getParent(), Addr, Inst, -1}; + } + + static ReachingMemVal getClobber(const Value *Addr, Instruction *Inst, + int32_t Offset = -1) { + return {DepKind::Clobber, Inst->getParent(), Addr, Inst, Offset}; + } + }; + + struct DependencyBlockInfo { + DependencyBlockInfo() = delete; + DependencyBlockInfo(const PHITransAddr &Addr, MemoryAccess *ClobberMA) + : Addr(Addr), InitialClobberMA(ClobberMA), ClobberMA(ClobberMA), + ForceUnknown(false), Visited(false) {} + PHITransAddr Addr; + MemoryAccess *InitialClobberMA; + MemoryAccess *ClobberMA; + std::optional MemVal; + bool ForceUnknown : 1; + bool Visited : 1; + }; + + using DependencyBlockSet = DenseMap; + + std::optional scanMemoryAccessesUsers( + const MemoryLocation &Loc, bool IsInvariantLoad, BasicBlock *BB, + const SmallVectorImpl &ClobbersList, MemorySSA &MSSA, + BatchAAResults &AA, LoadInst *L = nullptr); + + std::optional + accessMayModifyLocation(MemoryAccess *ClobberMA, const MemoryLocation &Loc, + bool IsInvariantLoad, BasicBlock *BB, MemorySSA &MSSA, + BatchAAResults &AA); + + bool collectPredecessors(BasicBlock *BB, const PHITransAddr &Addr, + MemoryAccess *ClobberMA, DependencyBlockSet &Blocks, + SmallVectorImpl &Worklist); + + void collectClobberList(SmallVectorImpl &Clobbers, + BasicBlock *BB, const DependencyBlockInfo &StartInfo, + const DependencyBlockSet &Blocks, MemorySSA &MSSA); + + bool findReachingValuesForLoad(LoadInst *Inst, + SmallVectorImpl &Values, + MemorySSA &MSSA, AAResults &AA); + // Helper functions of redundant load elimination. bool processLoad(LoadInst *L); bool processMaskedLoad(IntrinsicInst *I); bool processNonLocalLoad(LoadInst *L); + bool processNonLocalLoad(LoadInst *L, SmallVectorImpl &Deps); bool processAssumeIntrinsic(AssumeInst *II); /// Given a local dependency (Def or Clobber) determine if a value is /// available for the load. std::optional - AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, Value *Address); + AnalyzeLoadAvailability(LoadInst *Load, const ReachingMemVal &Dep, + Value *Address); /// Given a list of non-local dependencies, determine if a value is /// available for the load in each specified block. If it is, add it to /// ValuesPerBlock. If not, add it to UnavailableBlocks. - void AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps, + void AnalyzeLoadAvailability(LoadInst *Load, + SmallVectorImpl &Deps, AvailValInBlkVect &ValuesPerBlock, UnavailBlkVect &UnavailableBlocks); diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 72e1131a54a86..9eb1cf52d5013 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -116,6 +116,11 @@ static cl::opt GVNEnableMemDep("enable-gvn-memdep", cl::init(true)); static cl::opt GVNEnableMemorySSA("enable-gvn-memoryssa", cl::init(false)); +static cl::opt ScanUsersLimit( + "gvn-scan-users-limit", cl::Hidden, cl::init(100), + cl::desc("The number of memory accesses to scan in a block in reaching " + "memory values analysis (default = 100)")); + static cl::opt MaxNumDeps( "gvn-max-num-deps", cl::Hidden, cl::init(100), cl::desc("Max number of dependences to attempt Load PRE (default = 100)")); @@ -887,7 +892,8 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) { auto *MemDep = isMemDepEnabled() ? &AM.getResult(F) : nullptr; auto &LI = AM.getResult(F); - auto *MSSA = AM.getCachedResult(F); + auto *MSSA = + isMemorySSAEnabled() ? AM.getCachedResult(F) : nullptr; if (isMemorySSAEnabled() && !MSSA) { assert(!MemDep && "On-demand computation of MemSSA implies that MemDep is disabled!"); @@ -1280,7 +1286,7 @@ static const Instruction *findMayClobberedPtrAccess(LoadInst *Load, /// Try to locate the three instruction involved in a missed /// load-elimination case that is due to an intervening store. -static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo, +static void reportMayClobberedLoad(LoadInst *Load, Instruction *DepInst, const DominatorTree *DT, OptimizationRemarkEmitter *ORE) { using namespace ore; @@ -1293,7 +1299,7 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo, if (OtherAccess) R << " in favor of " << NV("OtherAccess", OtherAccess); - R << " because it is clobbered by " << NV("ClobberedBy", DepInfo.getInst()); + R << " because it is clobbered by " << NV("ClobberedBy", DepInst); ORE->emit(R); } @@ -1321,15 +1327,16 @@ static Value *findDominatingValue(const MemoryLocation &Loc, Type *LoadTy, } std::optional -GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, +GVNPass::AnalyzeLoadAvailability(LoadInst *Load, const ReachingMemVal &Dep, Value *Address) { assert(Load->isUnordered() && "rules below are incorrect for ordered access"); - assert(DepInfo.isLocal() && "expected a local dependence"); + assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) && + "expected a local dependence"); - Instruction *DepInst = DepInfo.getInst(); + Instruction *DepInst = Dep.Inst; const DataLayout &DL = Load->getDataLayout(); - if (DepInfo.isClobber()) { + if (Dep.Kind == DepKind::Clobber) { // If the dependence is to a store that writes to a superset of the bits // read by the load, we can extract the bits we need for the load from the // stored value. @@ -1354,17 +1361,23 @@ GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, if (DepLoad != Load && Address && Load->isAtomic() <= DepLoad->isAtomic()) { Type *LoadType = Load->getType(); - int Offset = -1; - - // If MD reported clobber, check it was nested. - if (DepInfo.isClobber() && - canCoerceMustAliasedValueToLoad(DepLoad, LoadType, - DepLoad->getFunction())) { - const auto ClobberOff = MD->getClobberOffset(DepLoad); - // GVN has no deal with a negative offset. - Offset = (ClobberOff == std::nullopt || *ClobberOff < 0) - ? -1 - : *ClobberOff; + int Offset = Dep.Offset; + + if (MD && !MSSAU) { + // If MD reported clobber, check it was nested. + if (canCoerceMustAliasedValueToLoad(DepLoad, LoadType, + DepLoad->getFunction())) { + const auto ClobberOff = MD->getClobberOffset(DepLoad); + // GVN has no deal with a negative offset. + Offset = (ClobberOff == std::nullopt || *ClobberOff < 0) + ? -1 + : *ClobberOff; + } + } else { + if (!canCoerceMustAliasedValueToLoad(DepLoad, LoadType, + DepLoad->getFunction()) || + Offset < 0) + Offset = -1; } if (Offset == -1) Offset = @@ -1391,11 +1404,11 @@ GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, dbgs() << "GVN: load "; Load->printAsOperand(dbgs()); dbgs() << " is clobbered by " << *DepInst << '\n';); if (ORE->allowExtraAnalysis(DEBUG_TYPE)) - reportMayClobberedLoad(Load, DepInfo, DT, ORE); + reportMayClobberedLoad(Load, DepInst, DT, ORE); return std::nullopt; } - assert(DepInfo.isDef() && "follows from above"); + assert(Dep.Kind == DepKind::Def && "follows from above"); // Loading the alloca -> undef. // Loading immediately after lifetime begin -> undef. @@ -1463,7 +1476,8 @@ GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo, return std::nullopt; } -void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps, +void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, + SmallVectorImpl &Deps, AvailValInBlkVect &ValuesPerBlock, UnavailBlkVect &UnavailableBlocks) { // Filter out useless results (non-locals, etc). Keep track of the blocks @@ -1471,8 +1485,7 @@ void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps, // dependencies that produce an unknown value for the load (such as a call // that could potentially clobber the load). for (const auto &Dep : Deps) { - BasicBlock *DepBB = Dep.getBB(); - MemDepResult DepInfo = Dep.getResult(); + BasicBlock *DepBB = Dep.Block; if (DeadBlocks.count(DepBB)) { // Dead dependent mem-op disguise as a load evaluating the same value @@ -1481,7 +1494,7 @@ void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps, continue; } - if (!DepInfo.isLocal()) { + if (Dep.Kind == DepKind::Other) { UnavailableBlocks.push_back(DepBB); continue; } @@ -1489,7 +1502,8 @@ void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps, // The address being loaded in this non-local block may not be the same as // the pointer operand of the load if PHI translation occurs. Make sure // to consider the right address. - if (auto AV = AnalyzeLoadAvailability(Load, DepInfo, Dep.getAddress())) { + if (auto AV = + AnalyzeLoadAvailability(Load, Dep, const_cast(Dep.Addr))) { // subtlety: because we know this was a non-local dependency, we know // it's safe to materialize anywhere between the instruction within // DepInfo and the end of it's block. @@ -1545,12 +1559,24 @@ LoadInst *GVNPass::findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB, if (!Inst.isIdenticalTo(Load)) continue; - MemDepResult Dep = MD->getDependency(&Inst); + bool HasLocalDep = true; + if (MD && !MSSAU) { + MemDepResult Dep = MD->getDependency(&Inst); + HasLocalDep = !Dep.isNonLocal(); + } else { + auto *MSSA = MSSAU->getMemorySSA(); + // Do not hoist if the identical load has ordering constraint. + if (auto *MA = MSSA->getMemoryAccess(&Inst); MA && isa(MA)) { + auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA); + HasLocalDep = isa(Clobber) && Clobber->getBlock() == SuccBB; + } + } + // If an identical load doesn't depends on any local instructions, it can // be safely moved to PredBB. // Also check for the implicit control flow instructions. See the comments // in PerformLoadPRE for details. - if (Dep.isNonLocal() && !ICF->isDominatedByICFIFromSameBlock(&Inst)) + if (!HasLocalDep && !ICF->isDominatedByICFIFromSameBlock(&Inst)) return cast(&Inst); // Otherwise there is something in the same BB clobbers the memory, we can't @@ -1607,7 +1633,8 @@ void GVNPass::eliminatePartiallyRedundantLoad( // Add the newly created load. ValuesPerBlock.push_back( AvailableValueInBlock::get(UnavailableBlock, NewLoad)); - MD->invalidateCachedPointerInfo(LoadPtr); + if (MD) + MD->invalidateCachedPointerInfo(LoadPtr); LLVM_DEBUG(dbgs() << "GVN INSERTED " << *NewLoad << '\n'); // For PredBB in CriticalEdgePredAndLoad we need to replace the uses of old @@ -1637,7 +1664,7 @@ void GVNPass::eliminatePartiallyRedundantLoad( V->takeName(Load); if (Instruction *I = dyn_cast(V)) I->setDebugLoc(Load->getDebugLoc()); - if (V->getType()->isPtrOrPtrVectorTy()) + if (MD && V->getType()->isPtrOrPtrVectorTy()) MD->invalidateCachedPointerInfo(V); ORE->emit([&]() { return OptimizationRemark(DEBUG_TYPE, "LoadPRE", Load) @@ -1992,13 +2019,11 @@ static void reportLoadElim(LoadInst *Load, Value *AvailableValue, /// non-local by performing PHI construction. bool GVNPass::processNonLocalLoad(LoadInst *Load) { // Non-local speculations are not allowed under asan. - if (Load->getParent()->getParent()->hasFnAttribute( - Attribute::SanitizeAddress) || - Load->getParent()->getParent()->hasFnAttribute( - Attribute::SanitizeHWAddress)) + if (Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) || + Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress)) return false; - // Step 1: Find the non-local dependencies of the load. + // Find the non-local dependencies of the load. LoadDepVect Deps; MD->getNonLocalPointerDependency(Load, Deps); @@ -2009,10 +2034,27 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) { if (NumDeps > MaxNumDeps) return false; + SmallVector MemVals; + for (const NonLocalDepResult &Dep : Deps) { + Value *Address = Dep.getAddress(); + BasicBlock *BB = Dep.getBB(); + Instruction *Inst = Dep.getResult().getInst(); + if (Dep.getResult().isClobber()) + MemVals.emplace_back(ReachingMemVal::getClobber(Address, Inst)); + else if (Dep.getResult().isDef()) + MemVals.emplace_back(ReachingMemVal::getDef(Address, Inst)); + else + MemVals.emplace_back(ReachingMemVal::getUnknown(BB, Address, Inst)); + } + + return processNonLocalLoad(Load, MemVals); +} + +bool GVNPass::processNonLocalLoad(LoadInst *Load, + SmallVectorImpl &Deps) { // If we had a phi translation failure, we'll have a single entry which is a // clobber in the current block. Reject this early. - if (NumDeps == 1 && - !Deps[0].getResult().isDef() && !Deps[0].getResult().isClobber()) { + if (Deps.size() == 1 && Deps[0].Kind == DepKind::Other) { LLVM_DEBUG(dbgs() << "GVN: non-local load "; Load->printAsOperand(dbgs()); dbgs() << " has unknown dependencies\n";); return false; @@ -2027,7 +2069,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) { Changed |= performScalarPRE(I); } - // Step 2: Analyze the availability of the load. + // Step 1: Analyze the availability of the load. AvailValInBlkVect ValuesPerBlock; UnavailBlkVect UnavailableBlocks; AnalyzeLoadAvailability(Load, Deps, ValuesPerBlock, UnavailableBlocks); @@ -2037,7 +2079,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) { if (ValuesPerBlock.empty()) return Changed; - // Step 3: Eliminate fully redundancy. + // Step 2: Eliminate fully redundancy. // // If all of the instructions we depend on produce a known value for this // load, then it is fully redundant and we can use PHI insertion to compute @@ -2059,7 +2101,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) { // to propagate Load's DebugLoc because Load may not post-dominate I. if (Load->getDebugLoc() && Load->getParent() == I->getParent()) I->setDebugLoc(Load->getDebugLoc()); - if (V->getType()->isPtrOrPtrVectorTy()) + if (MD && V->getType()->isPtrOrPtrVectorTy()) MD->invalidateCachedPointerInfo(V); ++NumGVNLoad; reportLoadElim(Load, V, ORE); @@ -2067,7 +2109,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) { return true; } - // Step 4: Eliminate partial redundancy. + // Step 3: Eliminate partial redundancy. if (!isPREEnabled() || !isLoadPREEnabled()) return Changed; if (!isLoadInLoopPREEnabled() && LI->getLoopFor(Load->getParent())) @@ -2146,10 +2188,530 @@ static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl) { I->replaceAllUsesWith(Repl); } +/// If a load has !invariant.group, try to find the most-dominating instruction +/// with the same metadata and equivalent pointer (modulo bitcasts and zero +/// GEPs). If one is found that dominates the load, its value can be reused. +static Instruction *findInvariantGroupValue(LoadInst *L, DominatorTree &DT) { + Value *PointerOperand = L->getPointerOperand()->stripPointerCasts(); + + // It's not safe to walk the use list of a global value because function + // passes aren't allowed to look outside their functions. + // FIXME: this could be fixed by filtering instructions from outside of + // current function. + if (isa(PointerOperand)) + return nullptr; + + // Queue to process all pointers that are equivalent to load operand. + SmallVector PointerUsesQueue; + PointerUsesQueue.push_back(PointerOperand); + + Instruction *MostDominatingInstruction = L; + + // FIXME: This loop is potentially O(n^2) due to repeated dominates checks. + while (!PointerUsesQueue.empty()) { + Value *Ptr = PointerUsesQueue.pop_back_val(); + assert(Ptr && !isa(Ptr) && + "Null or GlobalValue should not be inserted"); + + for (User *U : Ptr->users()) { + auto *I = dyn_cast(U); + if (!I || I == L || !DT.dominates(I, MostDominatingInstruction)) + continue; + + // Add bitcasts and zero GEPs to queue. + // TODO: Should drop bitcast? + if (isa(I) || + (isa(I) && + cast(I)->hasAllZeroIndices())) { + PointerUsesQueue.push_back(I); + continue; + } + + // If we hit a load/store with an invariant.group metadata and the same + // pointer operand, we can assume that value pointed to by the pointer + // operand didn't change. + if (I->hasMetadata(LLVMContext::MD_invariant_group) && + Ptr == getLoadStorePointerOperand(I) && !I->isVolatile()) + MostDominatingInstruction = I; + } + } + + return MostDominatingInstruction != L ? MostDominatingInstruction : nullptr; +} + +// Return the memory location accessed by the (masked) load/store instruction +// `I`, if the instruction could potentially provide a useful value for +// eliminating the load. +static std::optional +maybeLoadStoreLocation(Instruction *I, bool AllowStores, + const TargetLibraryInfo *TLI) { + if (auto *LI = dyn_cast(I)) + return MemoryLocation::get(LI); + + if (auto *II = dyn_cast(I)) { + switch (II->getIntrinsicID()) { + case Intrinsic::masked_load: + return MemoryLocation::getForArgument(II, 0, TLI); + case Intrinsic::masked_store: + if (AllowStores) + return MemoryLocation::getForArgument(II, 1, TLI); + return std::nullopt; + default: + break; + } + } + + if (!AllowStores) + return std::nullopt; + + if (auto *SI = dyn_cast(I)) + return MemoryLocation::get(SI); + return std::nullopt; +} + +std::optional GVNPass::scanMemoryAccessesUsers( + const MemoryLocation &Loc, bool IsInvariantLoad, BasicBlock *BB, + const SmallVectorImpl &ClobbersList, MemorySSA &MSSA, + BatchAAResults &AA, LoadInst *L) { + + // Prefer a candidate that is closer to the load within the same block. + auto UpdateChoice = [&](std::optional &Choice, + AliasResult &AR, Instruction *Candidate) { + if (!Choice) { + if (AR == AliasResult::PartialAlias) + Choice = ReachingMemVal::getClobber(Loc.Ptr, Candidate, AR.getOffset()); + else + Choice = ReachingMemVal::getDef(Loc.Ptr, Candidate); + return; + } + if (!MSSA.locallyDominates(MSSA.getMemoryAccess(Choice->Inst), + MSSA.getMemoryAccess(Candidate))) + return; + + if (AR == AliasResult::PartialAlias) { + Choice->Kind = DepKind::Clobber; + Choice->Offset = AR.getOffset(); + } else { + Choice->Kind = DepKind::Def; + Choice->Offset = -1; + } + + Choice->Inst = Candidate; + Choice->Block = Candidate->getParent(); + }; + + std::optional ReachingVal; + for (MemoryAccess *MA : ClobbersList) { + unsigned Scanned = 0; + for (User *U : MA->users()) { + if (++Scanned >= ScanUsersLimit) + return ReachingMemVal::getUnknown(BB, Loc.Ptr); + + auto *UseOrDef = dyn_cast(U); + if (!UseOrDef || UseOrDef->getBlock() != BB) + continue; + + Instruction *MemI = UseOrDef->getMemoryInst(); + if (MemI == L || + (L && !MSSA.locallyDominates(UseOrDef, MSSA.getMemoryAccess(L)))) + continue; + + if (auto MaybeLoc = maybeLoadStoreLocation(MemI, IsInvariantLoad, TLI)) { + AliasResult AR = AA.alias(*MaybeLoc, Loc); + // If the locations do not certainly alias, we cannot possibly infer the + // following load loads the same value. + if (AR == AliasResult::NoAlias || AR == AliasResult::MayAlias) + continue; + + // Locations partially overlap, but neither is a subset of the other, or + // the second location is before the first. + if (AR == AliasResult::PartialAlias && + (!AR.hasOffset() || AR.getOffset() < 0)) + continue; + + // Found candidate, the new load memory location and the given location + // must alias: precise overlap, or subset with non-negative offset. + UpdateChoice(ReachingVal, AR, MemI); + } + } + if (ReachingVal) + break; + } + + return ReachingVal; +} + +/// Check if a given MemoryAccess (usually a MemoryDef) actually modifies a +/// given location. +std::optional GVNPass::accessMayModifyLocation( + MemoryAccess *ClobberMA, const MemoryLocation &Loc, bool IsInvariantLoad, + BasicBlock *BB, MemorySSA &MSSA, BatchAAResults &AA) { + assert(ClobberMA->getBlock() == BB); + + // If the clobbering access is the entry memory state, we cannot say anything + // about the content of the memory, except when we are accessing a local + // object, which can be turned later into producing `undef`. + if (MSSA.isLiveOnEntryDef(ClobberMA)) { + if (auto *Alloc = dyn_cast(getUnderlyingObject(Loc.Ptr))) + if (Alloc->getParent() == BB) + return ReachingMemVal::getDef(Loc.Ptr, const_cast(Alloc)); + return ReachingMemVal::getUnknown(BB, Loc.Ptr); + } + + // Loads from "constant" memory can't be clobbered. + if (IsInvariantLoad || AA.pointsToConstantMemory(Loc)) + return std::nullopt; + + auto GetOrdering = [](const Instruction *I) { + if (auto *L = dyn_cast(I)) + return L->getOrdering(); + return cast(I)->getOrdering(); + }; + Instruction *ClobberI = cast(ClobberMA)->getMemoryInst(); + + // Check if the clobbering access is a load or a store that we can reuse. + if (auto MaybeLoc = maybeLoadStoreLocation(ClobberI, true, TLI)) { + AliasResult AR = AA.alias(*MaybeLoc, Loc); + if (AR == AliasResult::MustAlias) + return ReachingMemVal::getDef(Loc.Ptr, ClobberI); + + if (AR == AliasResult::NoAlias) { + // If the locations do not alias we may still be able to skip over the + // clobbering instruction, even if it is atomic. + // The original load is either non-atomic or unordered. We can reorder + // these across non-atomic, unordered or monotonic loads or across any + // store. + if (!ClobberI->isAtomic() || + !isStrongerThan(GetOrdering(ClobberI), AtomicOrdering::Monotonic) || + isa(ClobberI)) + return std::nullopt; + return ReachingMemVal::getClobber(Loc.Ptr, ClobberI); + } + + // Skip over volatile loads (the original load is non-volatile, non-atomic). + if (!ClobberI->isAtomic() && isa(ClobberI)) + return std::nullopt; + + if (AR == AliasResult::MayAlias || + (AR == AliasResult::PartialAlias && + (!AR.hasOffset() || AR.getOffset() < 0))) + return ReachingMemVal::getClobber(Loc.Ptr, ClobberI); + + // The only option left is a store of the superset of the required bits. + assert(AR == AliasResult::PartialAlias && AR.hasOffset() && + AR.getOffset() > 0 && + "Must be the superset/partial overlap case with positive offset"); + return ReachingMemVal::getClobber(Loc.Ptr, ClobberI, AR.getOffset()); + } + + if (auto *II = dyn_cast(ClobberI)) { + if (isa(II)) + return std::nullopt; + if (II->getIntrinsicID() == Intrinsic::lifetime_start) { + MemoryLocation IIObjLoc = MemoryLocation::getForArgument(II, 0, TLI); + if (AA.isMustAlias(IIObjLoc, Loc)) + return ReachingMemVal::getDef(Loc.Ptr, ClobberI); + return std::nullopt; + } + } + + // If we are at a malloc-like function call, we can turn the load into `undef` + // or zero. + if (isNoAliasCall(ClobberI)) { + const Value *Obj = getUnderlyingObject(Loc.Ptr); + if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.Ptr)) + return ReachingMemVal::getDef(Loc.Ptr, ClobberI); + } + + // Can reorder loads across a release fence. + if (auto *FI = dyn_cast(ClobberI)) + if (FI->getOrdering() == AtomicOrdering::Release) + return std::nullopt; + + // See if the clobber instruction (e.g., a generic call) may modify the + // location. + ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc); + // If may modify the location, analyze deeper, to exclude accesses to + // non-escaping local allocations. + if (MR == ModRefInfo::NoModRef || MR == ModRefInfo::Ref) + return std::nullopt; + + // Conservatively assume the clobbering memory access may overwrite the + // location. + return ReachingMemVal::getClobber(Loc.Ptr, ClobberI); +} + +/// Collect the predecessors of block, while doing phi-translation of the memory +/// address and the memory clobber. Return false if the block should be marked +/// as clobbering the memory location in an unknown way. +bool GVNPass::collectPredecessors(BasicBlock *BB, const PHITransAddr &Addr, + MemoryAccess *ClobberMA, + DependencyBlockSet &Blocks, + SmallVectorImpl &Worklist) { + if (Addr.needsPHITranslationFromBlock(BB) && + !Addr.isPotentiallyPHITranslatable()) + return false; + + auto *MPhi = + ClobberMA->getBlock() == BB ? dyn_cast(ClobberMA) : nullptr; + SmallVector, 8> Preds; + for (BasicBlock *Pred : predecessors(BB)) { + // Skip unreachable predecessors. + if (!DT->isReachableFromEntry(Pred)) + continue; + + // Skip already visited predecessors. + if (llvm::any_of(Preds, [Pred](const auto &P) { return P.first == Pred; })) + continue; + + PHITransAddr TransAddr = Addr; + if (TransAddr.needsPHITranslationFromBlock(BB)) + TransAddr.translateValue(BB, Pred, DT, false); + + auto It = Blocks.find(Pred); + if (It != Blocks.end()) { + // If we reach a visited block with a different address, set the + // current block as clobbering the memory location in an unknown way + // (by returning false). + if (It->second.Addr.getAddr() != TransAddr.getAddr()) + return false; + // Otherwise, just stop the traversal. + continue; + } + + Preds.emplace_back( + Pred, DependencyBlockInfo(TransAddr, + MPhi ? MPhi->getIncomingValueForBlock(Pred) + : ClobberMA)); + } + + // We collected the predecessors and stored them in Preds. Now, populate the + // worklist with the predecessors found, and cache the eventual translated + // address for each block. + for (auto &P : Preds) { + [[maybe_unused]] auto It = + Blocks.try_emplace(P.first, std::move(P.second)).first; + Worklist.push_back(P.first); + } + + return true; +} + +/// Gather a list of memory clobbers, such that their memory uses could +/// potentially alias our memory location. +void GVNPass::collectClobberList(SmallVectorImpl &Clobbers, + BasicBlock *BB, + const DependencyBlockInfo &StartInfo, + const DependencyBlockSet &Blocks, + MemorySSA &MSSA) { + MemoryAccess *MA = StartInfo.InitialClobberMA; + MemoryAccess *LastMA = StartInfo.ClobberMA; + + for (;;) { + while (MA != LastMA) { + Clobbers.push_back(MA); + MA = cast(MA)->getDefiningAccess(); + } + Clobbers.push_back(MA); + + if (MSSA.isLiveOnEntryDef(MA) || + (MA->getBlock() == BB && !isa(MA))) + break; + + if (MA->getBlock() == BB) + BB = DT->getNode(BB)->getIDom()->getBlock(); + else + BB = MA->getBlock(); + + auto It = Blocks.find(BB); + if (It == Blocks.end()) + break; + + MA = It->second.InitialClobberMA; + LastMA = It->second.ClobberMA; + if (MA == Clobbers.back()) + Clobbers.pop_back(); + } +} + +/// Find the set of all the reaching memory definitions for the location +/// referred to by the pointer operand of the given load instruction. Definitely +/// aliasing memory reads are treated as definitions, for the purposes of this +/// function. +bool GVNPass::findReachingValuesForLoad(LoadInst *L, + SmallVectorImpl &Values, + MemorySSA &MSSA, AAResults &AAR) { + EarliestEscapeAnalysis EA(*DT, LI); + BatchAAResults AA(AAR, &EA); + BasicBlock *StartBlock = L->getParent(); + bool IsInvariantLoad = L->hasMetadata(LLVMContext::MD_invariant_load); + MemoryAccess *ClobberMA = MSSA.getMemoryAccess(L)->getDefiningAccess(); + const MemoryLocation Loc = MemoryLocation::get(L); + + // Fast path for load tagged with !invariant.group. + if (L->hasMetadata(LLVMContext::MD_invariant_group)) { + if (Instruction *G = findInvariantGroupValue(L, *DT)) { + Values.emplace_back( + ReachingMemVal::getDef(getLoadStorePointerOperand(G), G)); + return true; + } + } + + // First off, look for a local dependency. Doing this allows us to avoid + // having to disambiguate between the parts of the initial basic block before + // and after the original load instruction (when entered from a backedge). + do { + // Scan users of the clobbering memory access. + if (auto RMV = scanMemoryAccessesUsers( + Loc, IsInvariantLoad, StartBlock, + SmallVector{ClobberMA}, MSSA, AA, L)) { + Values.emplace_back(*RMV); + return true; + } + + // Proceed visiting predecessors if the clobbering access is non-local or it + // is a MemoryPhi. + if (ClobberMA->getBlock() != StartBlock || isa(ClobberMA)) + break; + + // Check if the clobber actually aliases the load location. + if (auto RMV = accessMayModifyLocation(ClobberMA, Loc, IsInvariantLoad, + StartBlock, MSSA, AA)) { + Values.emplace_back(*RMV); + return true; + } + + // It may happen that the clobbering memory access does not actually + // clobber our load location, transition to its defining memory access. + ClobberMA = cast(ClobberMA)->getDefiningAccess(); + } while (ClobberMA->getBlock() == StartBlock); + + // Non-local speculations are not allowed under ASan. + if (L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) || + L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress)) + return false; + + // Walk backwards through the CFG, collecting blocks along the way, + // terminating at blocks/instructions, which definitely define our memory + // location (perhaps in an unknown way). Start off by collecting the + // predecessors of the initial basic block as starting points for the walk. + DependencyBlockSet Blocks; + SmallVector InitialWorklist; + const DataLayout &DL = L->getModule()->getDataLayout(); + if (!collectPredecessors(StartBlock, + PHITransAddr(L->getPointerOperand(), DL, AC), + ClobberMA, Blocks, InitialWorklist)) + return false; + + // Do a bottom-up depth-first search. + auto Worklist = InitialWorklist; + while (!Worklist.empty()) { + auto *BB = Worklist.pop_back_val(); + DependencyBlockInfo &Info = Blocks.find(BB)->second; + + // Phi-translation may have failed. + if (!Info.Addr.getAddr()) + continue; + + // If the clobbering memory access is in the current block and it indeed + // clobbers our load location, record the dependency and stop the + // traversal. + if (Info.ClobberMA->getBlock() == BB && !isa(Info.ClobberMA)) { + if (auto RMV = accessMayModifyLocation( + Info.ClobberMA, Loc.getWithNewPtr(Info.Addr.getAddr()), + IsInvariantLoad, BB, MSSA, AA)) { + Info.MemVal = RMV; + continue; + } + assert(!MSSA.isLiveOnEntryDef(Info.ClobberMA) && + "LiveOnEntry aliases everything"); + + // If, however, the clobbering memory access does not actually clobber + // our load location, transition to its defining memory access, but + // keep examining the same basic block. + Info.ClobberMA = + cast(Info.ClobberMA)->getDefiningAccess(); + Worklist.emplace_back(BB); + continue; + } + + // At this point we know the current block is "transparent", i.e. the memory + // location is not modified when execution goes through this block. + // Continue to its predecessors, unless a predecessor has already been + // visited with a different address. We currently cannot represent such a + // dependency. + if (BB == StartBlock && Info.Addr.getAddr() != L->getPointerOperand()) { + Info.ForceUnknown = true; + continue; + } + if (BB != StartBlock && + !collectPredecessors(BB, Info.Addr, Info.ClobberMA, Blocks, Worklist)) + Info.ForceUnknown = true; + } + + // Now we have collected all the blocks, that write a (possibly unknown) + // value to our memory location and that there exists a path to the load + // instruction, along which the memory location is not modified. Do a second + // traversal, looking at memory loads. + Worklist = InitialWorklist; + for (BasicBlock *BB : Worklist) { + DependencyBlockInfo &Info = Blocks.find(BB)->second; + Info.Visited = true; + } + + SmallVector Clobbers; + while (!Worklist.empty()) { + auto *BB = Worklist.pop_back_val(); + DependencyBlockInfo &Info = Blocks.find(BB)->second; + + // If phi-translation failed, assume the memory location is modified in + // unknown way. + if (!Info.Addr.getAddr()) { + Values.push_back(ReachingMemVal::getUnknown(BB, nullptr)); + continue; + } + + Clobbers.clear(); + collectClobberList(Clobbers, BB, Info, Blocks, MSSA); + if (auto RMV = + scanMemoryAccessesUsers(Loc.getWithNewPtr(Info.Addr.getAddr()), + IsInvariantLoad, BB, Clobbers, MSSA, AA)) { + Values.push_back(*RMV); + continue; + } + + // If no reusable memory use was found, and the current block is not + // transparent, use the already established memory def. + if (Info.MemVal) { + Values.push_back(*Info.MemVal); + continue; + } + + if (Info.ForceUnknown) { + Values.push_back(ReachingMemVal::getUnknown(BB, Info.Addr.getAddr())); + continue; + } + + // If the current block is transparent, continue to its predecessors. + for (BasicBlock *Pred : predecessors(BB)) { + auto It = Blocks.find(Pred); + if (It == Blocks.end()) + continue; + DependencyBlockInfo &PredInfo = It->second; + if (PredInfo.Visited) + continue; + PredInfo.Visited = true; + Worklist.push_back(Pred); + } + } + + return true; +} + /// Attempt to eliminate a load, first by eliminating it /// locally, and then attempting non-local elimination if that fails. bool GVNPass::processLoad(LoadInst *L) { - if (!MD) + if (!MD && !MSSAU) return false; // This code hasn't been audited for ordered or volatile memory access. @@ -2164,15 +2726,33 @@ bool GVNPass::processLoad(LoadInst *L) { return true; } - // ... to a pointer that has been loaded from before... - MemDepResult Dep = MD->getDependency(L); + ReachingMemVal MemVal = ReachingMemVal::getUnknown(nullptr, nullptr); + if (MD && !MSSAU) { + // ... to a pointer that has been loaded from before... + MemDepResult Dep = MD->getDependency(L); + + // If it is defined in another block, try harder. + if (Dep.isNonLocal()) + return processNonLocalLoad(L); - // If it is defined in another block, try harder. - if (Dep.isNonLocal()) - return processNonLocalLoad(L); + // Only handle the local case below. + if (Dep.isDef()) + MemVal = ReachingMemVal::getDef(L->getPointerOperand(), Dep.getInst()); + else if (Dep.isClobber()) + MemVal = + ReachingMemVal::getClobber(L->getPointerOperand(), Dep.getInst()); + } else { + SmallVector MemVals; + if (!findReachingValuesForLoad(L, MemVals, *MSSAU->getMemorySSA(), *AA)) + return false; // Too many dependencies. + assert(MemVals.size() && "Expected at least an unknown value"); + if (MemVals.size() > 1 || MemVals[0].Block != L->getParent()) + return processNonLocalLoad(L, MemVals); + + MemVal = MemVals[0]; + } - // Only handle the local case below. - if (!Dep.isLocal()) { + if (MemVal.Kind == DepKind::Other) { // This might be a NonFuncLocal or an Unknown. LLVM_DEBUG( // fast print dep, using operator<< on instruction is too slow. @@ -2181,7 +2761,7 @@ bool GVNPass::processLoad(LoadInst *L) { return false; } - auto AV = AnalyzeLoadAvailability(L, Dep, L->getPointerOperand()); + auto AV = AnalyzeLoadAvailability(L, MemVal, L->getPointerOperand()); if (!AV) return false; @@ -2799,6 +3379,7 @@ bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT, DT = &RunDT; VN.setDomTree(DT); TLI = &RunTLI; + AA = &RunAA; VN.setAliasAnalysis(&RunAA); MD = RunMD; ImplicitControlFlowTracking ImplicitCFT; diff --git a/llvm/test/Analysis/TypeBasedAliasAnalysis/gvn-nonlocal-type-mismatch.ll b/llvm/test/Analysis/TypeBasedAliasAnalysis/gvn-nonlocal-type-mismatch.ll index 685c0159dd21d..f314bcadfa516 100644 --- a/llvm/test/Analysis/TypeBasedAliasAnalysis/gvn-nonlocal-type-mismatch.ll +++ b/llvm/test/Analysis/TypeBasedAliasAnalysis/gvn-nonlocal-type-mismatch.ll @@ -8,64 +8,16 @@ target datalayout = "e-p:64:64:64" ; fully redundant. define void @yes(i1 %c, ptr %p, ptr %p1, ptr %q) nounwind { -; CHECK-MEMDEP-LABEL: define void @yes( -; CHECK-MEMDEP-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]] -; CHECK-MEMDEP-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0:![0-9]+]] -; CHECK-MEMDEP-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3:![0-9]+]] -; CHECK-MEMDEP-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] -; CHECK-MEMDEP: [[IF_THEN]]: -; CHECK-MEMDEP-NEXT: store i32 0, ptr [[Q]], align 4 -; CHECK-MEMDEP-NEXT: ret void -; CHECK-MEMDEP: [[IF_ELSE]]: -; CHECK-MEMDEP-NEXT: ret void -; -; CHECK-MEMSSA-LABEL: define void @yes( -; CHECK-MEMSSA-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]] -; CHECK-MEMSSA-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0:![0-9]+]] -; CHECK-MEMSSA-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3:![0-9]+]] -; CHECK-MEMSSA-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] -; CHECK-MEMSSA: [[IF_THEN]]: -; CHECK-MEMSSA-NEXT: [[T:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[RED_TBAA0]] -; CHECK-MEMSSA-NEXT: store i32 [[T]], ptr [[Q]], align 4 -; CHECK-MEMSSA-NEXT: ret void -; CHECK-MEMSSA: [[IF_ELSE]]: -; CHECK-MEMSSA-NEXT: ret void -; -entry: - store i32 0, ptr %p, !tbaa !1 - store i32 1, ptr %p1, !tbaa !2 - br i1 %c, label %if.else, label %if.then - -if.then: - %t = load i32, ptr %p, !tbaa !1 - store i32 %t, ptr %q - ret void - -if.else: - ret void -} - -; GVN should ignore the store to p1 to see that the first load from p is -; fully redundant. However, the second load uses a different type. Theoretically -; the other type could be unified with the first type, however for now, GVN -; should just be conservative. - -define void @watch_out_for_type_change(i1 %c, ptr %p, ptr %p1, ptr %q) nounwind { -; CHECK-LABEL: define void @watch_out_for_type_change( +; CHECK-LABEL: define void @yes( ; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0:![0-9]+]] ; CHECK-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3:![0-9]+]] ; CHECK-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] ; CHECK: [[IF_THEN]]: -; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5:![0-9]+]] -; CHECK-NEXT: store i32 [[T]], ptr [[Q]], align 4 +; CHECK-NEXT: store i32 0, ptr [[Q]], align 4 ; CHECK-NEXT: ret void ; CHECK: [[IF_ELSE]]: -; CHECK-NEXT: [[U:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[BRICK_RED_TBAA8:![0-9]+]] -; CHECK-NEXT: store i32 [[U]], ptr [[Q]], align 4 ; CHECK-NEXT: ret void ; entry: @@ -74,47 +26,47 @@ entry: br i1 %c, label %if.else, label %if.then if.then: - %t = load i32, ptr %p, !tbaa !3 + %t = load i32, ptr %p, !tbaa !1 store i32 %t, ptr %q ret void if.else: - %u = load i32, ptr %p, !tbaa !4 - store i32 %u, ptr %q ret void } -; As before, but the types are swapped. This time GVN does managed to -; eliminate one of the loads before noticing the type mismatch. +; GVN should ignore the store to p1 to see that the first load from p is +; fully redundant. However, the second load uses a different type. Theoretically +; the other type could be unified with the first type, however for now, GVN +; should just be conservative. -define void @watch_out_for_another_type_change(i1 %c, ptr %p, ptr %p1, ptr %q) nounwind { -; CHECK-MEMDEP-LABEL: define void @watch_out_for_another_type_change( +define void @watch_out_for_type_change(i1 %c, ptr %p, ptr %p1, ptr %q) nounwind { +; CHECK-MEMDEP-LABEL: define void @watch_out_for_type_change( ; CHECK-MEMDEP-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] { ; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]] ; CHECK-MEMDEP-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0]] ; CHECK-MEMDEP-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3]] ; CHECK-MEMDEP-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] ; CHECK-MEMDEP: [[IF_THEN]]: -; CHECK-MEMDEP-NEXT: store i32 0, ptr [[Q]], align 4 +; CHECK-MEMDEP-NEXT: [[T:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5:![0-9]+]] +; CHECK-MEMDEP-NEXT: store i32 [[T]], ptr [[Q]], align 4 ; CHECK-MEMDEP-NEXT: ret void ; CHECK-MEMDEP: [[IF_ELSE]]: -; CHECK-MEMDEP-NEXT: [[U:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5]] +; CHECK-MEMDEP-NEXT: [[U:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[BRICK_RED_TBAA8:![0-9]+]] ; CHECK-MEMDEP-NEXT: store i32 [[U]], ptr [[Q]], align 4 ; CHECK-MEMDEP-NEXT: ret void ; -; CHECK-MEMSSA-LABEL: define void @watch_out_for_another_type_change( +; CHECK-MEMSSA-LABEL: define void @watch_out_for_type_change( ; CHECK-MEMSSA-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] { ; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]] ; CHECK-MEMSSA-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0]] ; CHECK-MEMSSA-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3]] ; CHECK-MEMSSA-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] ; CHECK-MEMSSA: [[IF_THEN]]: -; CHECK-MEMSSA-NEXT: [[T:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[BRICK_RED_TBAA8]] +; CHECK-MEMSSA-NEXT: [[T:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5:![0-9]+]] ; CHECK-MEMSSA-NEXT: store i32 [[T]], ptr [[Q]], align 4 ; CHECK-MEMSSA-NEXT: ret void ; CHECK-MEMSSA: [[IF_ELSE]]: -; CHECK-MEMSSA-NEXT: [[U:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5]] -; CHECK-MEMSSA-NEXT: store i32 [[U]], ptr [[Q]], align 4 +; CHECK-MEMSSA-NEXT: store i32 0, ptr [[Q]], align 4 ; CHECK-MEMSSA-NEXT: ret void ; entry: @@ -122,6 +74,40 @@ entry: store i32 1, ptr %p1, !tbaa !2 br i1 %c, label %if.else, label %if.then +if.then: + %t = load i32, ptr %p, !tbaa !3 + store i32 %t, ptr %q + ret void + +if.else: + %u = load i32, ptr %p, !tbaa !4 + store i32 %u, ptr %q + ret void +} + +; As before, but the types are swapped. This time GVN does managed to +; eliminate one of the loads before noticing the type mismatch. + +define void @watch_out_for_another_type_change(i1 %c, ptr %p, ptr %p1, ptr %q) nounwind { +; CHECK-LABEL: define void @watch_out_for_another_type_change( +; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: store i32 0, ptr [[P]], align 4, !tbaa [[RED_TBAA0]] +; CHECK-NEXT: store i32 1, ptr [[P1]], align 4, !tbaa [[BLU_TBAA3]] +; CHECK-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: store i32 0, ptr [[Q]], align 4 +; CHECK-NEXT: ret void +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: [[U:%.*]] = load i32, ptr [[P]], align 4, !tbaa [[OUTER_SPACE_TBAA5:![0-9]+]] +; CHECK-NEXT: store i32 [[U]], ptr [[Q]], align 4 +; CHECK-NEXT: ret void +; +entry: + store i32 0, ptr %p, !tbaa !1 + store i32 1, ptr %p1, !tbaa !2 + br i1 %c, label %if.else, label %if.then + if.then: %t = load i32, ptr %p, !tbaa !4 store i32 %t, ptr %q @@ -163,6 +149,4 @@ if.else: ; CHECK-MEMSSA: [[OUTER_SPACE_TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0} ; CHECK-MEMSSA: [[META6]] = !{!"outer space", [[META7:![0-9]+]]} ; CHECK-MEMSSA: [[META7]] = !{!"observable universe"} -; CHECK-MEMSSA: [[BRICK_RED_TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} -; CHECK-MEMSSA: [[META9]] = !{!"brick red", [[META1]]} ;. diff --git a/llvm/test/Transforms/GVN/PRE/load-metadata.ll b/llvm/test/Transforms/GVN/PRE/load-metadata.ll index 1128b1be199c2..836422987184c 100644 --- a/llvm/test/Transforms/GVN/PRE/load-metadata.ll +++ b/llvm/test/Transforms/GVN/PRE/load-metadata.ll @@ -3,32 +3,19 @@ ; RUN: opt -S -passes='gvn' < %s | FileCheck %s --check-prefixes=CHECK,MSSA define i32 @test1(ptr %p, i1 %C) { -; MDEP-LABEL: define i32 @test1( -; MDEP-SAME: ptr [[P:%.*]], i1 [[C:%.*]]) { -; MDEP-NEXT: [[BLOCK1:.*:]] -; MDEP-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MDEP: [[BLOCK2]]: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]], !invariant.group [[META1:![0-9]+]] -; MDEP-NEXT: br label %[[BLOCK4:.*]] -; MDEP: [[BLOCK3]]: -; MDEP-NEXT: store i32 0, ptr [[P]], align 4 -; MDEP-NEXT: br label %[[BLOCK4]] -; MDEP: [[BLOCK4]]: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[PRE_PRE]], %[[BLOCK2]] ] -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: define i32 @test1( -; MSSA-SAME: ptr [[P:%.*]], i1 [[C:%.*]]) { -; MSSA-NEXT: [[BLOCK1:.*:]] -; MSSA-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MSSA: [[BLOCK2]]: -; MSSA-NEXT: br label %[[BLOCK4:.*]] -; MSSA: [[BLOCK3]]: -; MSSA-NEXT: store i32 0, ptr [[P]], align 4 -; MSSA-NEXT: br label %[[BLOCK4]] -; MSSA: [[BLOCK4]]: -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]], !invariant.group [[META1:![0-9]+]] -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: define i32 @test1( +; CHECK-SAME: ptr [[P:%.*]], i1 [[C:%.*]]) { +; CHECK-NEXT: [[BLOCK1:.*:]] +; CHECK-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] +; CHECK: [[BLOCK2]]: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]], !invariant.group [[META1:![0-9]+]] +; CHECK-NEXT: br label %[[BLOCK4:.*]] +; CHECK: [[BLOCK3]]: +; CHECK-NEXT: store i32 0, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[BLOCK4]] +; CHECK: [[BLOCK4]]: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[PRE_PRE]], %[[BLOCK2]] ] +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -49,11 +36,9 @@ block4: !0 = !{i32 40, i32 100} !1 = !{!"magic ptr"} ;. -; MDEP: [[RNG0]] = !{i32 40, i32 100} -; MDEP: [[META1]] = !{!"magic ptr"} -;. -; MSSA: [[RNG0]] = !{i32 40, i32 100} -; MSSA: [[META1]] = !{!"magic ptr"} +; CHECK: [[RNG0]] = !{i32 40, i32 100} +; CHECK: [[META1]] = !{!"magic ptr"} ;. ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/lpre-call-wrap.ll b/llvm/test/Transforms/GVN/PRE/lpre-call-wrap.ll index 9b4eb6097ebb0..77072fdadb173 100644 --- a/llvm/test/Transforms/GVN/PRE/lpre-call-wrap.ll +++ b/llvm/test/Transforms/GVN/PRE/lpre-call-wrap.ll @@ -19,56 +19,31 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 %struct.A = type { i32, i32 } define void @_Z12testfunctionR1A(ptr %iter) { -; MDEP-LABEL: @_Z12testfunctionR1A( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = load i32, ptr [[ITER:%.*]], align 4 -; MDEP-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 -; MDEP-NEXT: br i1 [[TMP1]], label [[RETURN:%.*]], label [[BB_NPH:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_A:%.*]], ptr [[ITER]], i32 0, i32 1 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[DOTRLE:%.*]] = phi i32 [ [[TMP0]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB3_BACKEDGE:%.*]] ] -; MDEP-NEXT: [[TMP3:%.*]] = add i32 [[DOTRLE]], 1 -; MDEP-NEXT: store i32 [[TMP3]], ptr [[ITER]], align 4 -; MDEP-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4 -; MDEP-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP3]], [[TMP4]] -; MDEP-NEXT: br i1 [[TMP5]], label [[BB1:%.*]], label [[BB3_BACKEDGE]] -; MDEP: bb1: -; MDEP-NEXT: tail call void @_Z1gv() -; MDEP-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ITER]], align 4 -; MDEP-NEXT: br label [[BB3_BACKEDGE]] -; MDEP: bb3.backedge: -; MDEP-NEXT: [[TMP6]] = phi i32 [ [[DOTPRE]], [[BB1]] ], [ [[TMP3]], [[BB]] ] -; MDEP-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 -; MDEP-NEXT: br i1 [[TMP7]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @_Z12testfunctionR1A( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = load i32, ptr [[ITER:%.*]], align 4 -; MSSA-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 -; MSSA-NEXT: br i1 [[TMP1]], label [[RETURN:%.*]], label [[BB_NPH:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_A:%.*]], ptr [[ITER]], i32 0, i32 1 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[DOTRLE:%.*]] = phi i32 [ [[TMP0]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB3_BACKEDGE:%.*]] ] -; MSSA-NEXT: [[TMP3:%.*]] = add i32 [[DOTRLE]], 1 -; MSSA-NEXT: store i32 [[TMP3]], ptr [[ITER]], align 4 -; MSSA-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4 -; MSSA-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP3]], [[TMP4]] -; MSSA-NEXT: br i1 [[TMP5]], label [[BB1:%.*]], label [[BB3_BACKEDGE]] -; MSSA: bb1: -; MSSA-NEXT: tail call void @_Z1gv() -; MSSA-NEXT: br label [[BB3_BACKEDGE]] -; MSSA: bb3.backedge: -; MSSA-NEXT: [[TMP6]] = load i32, ptr [[ITER]], align 4 -; MSSA-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 -; MSSA-NEXT: br i1 [[TMP7]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @_Z12testfunctionR1A( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ITER:%.*]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[TMP1]], label [[RETURN:%.*]], label [[BB_NPH:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_A:%.*]], ptr [[ITER]], i32 0, i32 1 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[DOTRLE:%.*]] = phi i32 [ [[TMP0]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB3_BACKEDGE:%.*]] ] +; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[DOTRLE]], 1 +; CHECK-NEXT: store i32 [[TMP3]], ptr [[ITER]], align 4 +; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP3]], [[TMP4]] +; CHECK-NEXT: br i1 [[TMP5]], label [[BB1:%.*]], label [[BB3_BACKEDGE]] +; CHECK: bb1: +; CHECK-NEXT: tail call void @_Z1gv() +; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ITER]], align 4 +; CHECK-NEXT: br label [[BB3_BACKEDGE]] +; CHECK: bb3.backedge: +; CHECK-NEXT: [[TMP6]] = phi i32 [ [[DOTPRE]], [[BB1]] ], [ [[TMP3]], [[BB]] ] +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: %0 = getelementptr %struct.A, ptr %iter, i32 0, i32 0 ; [#uses=3] @@ -103,4 +78,5 @@ return: ; preds = %bb3.backedge, %entry declare void @_Z1gv() ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll b/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll index 1e789b0613f4f..6717469e08e1f 100644 --- a/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll +++ b/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll @@ -51,56 +51,32 @@ if.end: ; preds = %if.then, %entry } define void @test2(i64 %i) { -; MDEP-LABEL: @test2( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]] -; MDEP-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8 -; MDEP-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]] -; MDEP-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8 -; MDEP-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]] -; MDEP-NEXT: store i64 [[MUL]], ptr @g1, align 8 -; MDEP-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3 -; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; MDEP: if.then: -; MDEP-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo() -; MDEP-NEXT: store i64 [[CALL]], ptr @g2, align 8 -; MDEP-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @a, i64 24), align 8 -; MDEP-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @b, i64 24), align 8 -; MDEP-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]] -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: [[MUL5_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], [[IF_THEN]] ], [ [[MUL]], [[ENTRY:%.*]] ] -; MDEP-NEXT: [[T3:%.*]] = phi i64 [ [[T3_PRE]], [[IF_THEN]] ], [ [[T1]], [[ENTRY]] ] -; MDEP-NEXT: [[T2:%.*]] = phi i64 [ [[T2_PRE]], [[IF_THEN]] ], [ [[T0]], [[ENTRY]] ] -; MDEP-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY]] ] -; MDEP-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]] -; MDEP-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]] -; MDEP-NEXT: store i64 [[MUL5_PRE_PHI]], ptr @g3, align 8 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test2( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]] -; MSSA-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8 -; MSSA-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]] -; MSSA-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8 -; MSSA-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]] -; MSSA-NEXT: store i64 [[MUL]], ptr @g1, align 8 -; MSSA-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3 -; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo() -; MSSA-NEXT: store i64 [[CALL]], ptr @g2, align 8 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY:%.*]] ] -; MSSA-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]] -; MSSA-NEXT: [[T2:%.*]] = load i64, ptr [[ARRAYIDX3]], align 8 -; MSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]] -; MSSA-NEXT: [[T3:%.*]] = load i64, ptr [[ARRAYIDX4]], align 8 -; MSSA-NEXT: [[MUL5:%.*]] = mul nsw i64 [[T3]], [[T2]] -; MSSA-NEXT: store i64 [[MUL5]], ptr @g3, align 8 -; MSSA-NEXT: ret void +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]] +; CHECK-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8 +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]] +; CHECK-NEXT: store i64 [[MUL]], ptr @g1, align 8 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3 +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo() +; CHECK-NEXT: store i64 [[CALL]], ptr @g2, align 8 +; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @a, i64 24), align 8 +; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @b, i64 24), align 8 +; CHECK-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]] +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[MUL5_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], [[IF_THEN]] ], [ [[MUL]], [[ENTRY:%.*]] ] +; CHECK-NEXT: [[T3:%.*]] = phi i64 [ [[T3_PRE]], [[IF_THEN]] ], [ [[T1]], [[ENTRY]] ] +; CHECK-NEXT: [[T2:%.*]] = phi i64 [ [[T2_PRE]], [[IF_THEN]] ], [ [[T0]], [[ENTRY]] ] +; CHECK-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY]] ] +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]] +; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]] +; CHECK-NEXT: store i64 [[MUL5_PRE_PHI]], ptr @g3, align 8 +; CHECK-NEXT: ret void ; entry: %arrayidx = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 %i @@ -277,50 +253,29 @@ if.end3: ; preds = %if.then2, %if.else, ; available in if.then. Check that we correctly phi-translate to the phi that ; the load has been replaced with. define void @test6(ptr %ptr, i1 %arg) { -; MDEP-LABEL: @test6( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[ARRAYIDX1_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 -; MDEP-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX1_PHI_TRANS_INSERT]], align 4 -; MDEP-NEXT: br label [[WHILE:%.*]] -; MDEP: while: -; MDEP-NEXT: [[TMP0:%.*]] = phi i32 [ [[DOTPRE]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[IF_END:%.*]] ] -; MDEP-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[IF_END]] ] -; MDEP-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]] -; MDEP-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1 -; MDEP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]] -; MDEP-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 -; MDEP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] -; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]] -; MDEP: if.then: -; MDEP-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4 -; MDEP-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: [[TMP2]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[WHILE]] ] -; MDEP-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]] -; MDEP: while.end: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test6( -; MSSA-NEXT: entry: -; MSSA-NEXT: br label [[WHILE:%.*]] -; MSSA: while: -; MSSA-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[IF_END:%.*]] ] -; MSSA-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 [[I]] -; MSSA-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4 -; MSSA-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1 -; MSSA-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]] -; MSSA-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 -; MSSA-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] -; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]] -; MSSA: if.then: -; MSSA-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4 -; MSSA-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]] -; MSSA: while.end: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAYIDX1_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1 +; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX1_PHI_TRANS_INSERT]], align 4 +; CHECK-NEXT: br label [[WHILE:%.*]] +; CHECK: while: +; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[DOTPRE]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[IF_END:%.*]] ] +; CHECK-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[IF_END]] ] +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]] +; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1 +; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]] +; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]] +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]] +; CHECK: if.then: +; CHECK-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4 +; CHECK-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[TMP2]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[WHILE]] ] +; CHECK-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]] +; CHECK: while.end: +; CHECK-NEXT: ret void ; entry: br label %while @@ -350,40 +305,24 @@ while.end: ; Load from arrayidx2 is partially redundant, check that address translation can ; fold sext + trunc across phi node together. define i32 @test7(ptr noalias %ptr1, ptr noalias %ptr2, i32 %i, i1 %cond) { -; MDEP-LABEL: @test7( -; MDEP-NEXT: entry: -; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]] -; MDEP: entry.if.end_crit_edge: -; MDEP-NEXT: [[RES_PRE:%.*]] = load i32, ptr [[PTR1:%.*]], align 4 -; MDEP-NEXT: br label [[IF_END:%.*]] -; MDEP: if.then: -; MDEP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[I:%.*]] -; MDEP-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; MDEP-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4 -; MDEP-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: [[RES:%.*]] = phi i32 [ [[RES_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[TMP]], [[IF_THEN]] ] -; MDEP-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[IDX_EXT]], [[IF_THEN]] ] -; MDEP-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32 -; MDEP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]] -; MDEP-NEXT: ret i32 [[RES]] -; -; MSSA-LABEL: @test7( -; MSSA-NEXT: entry: -; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1:%.*]], i32 [[I:%.*]] -; MSSA-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 -; MSSA-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4 -; MSSA-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IDX_EXT]], [[IF_THEN]] ] -; MSSA-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32 -; MSSA-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]] -; MSSA-NEXT: [[RES:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 -; MSSA-NEXT: ret i32 [[RES]] +; CHECK-LABEL: @test7( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]] +; CHECK: entry.if.end_crit_edge: +; CHECK-NEXT: [[RES_PRE:%.*]] = load i32, ptr [[PTR1:%.*]], align 4 +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[I:%.*]] +; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +; CHECK-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4 +; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[RES_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[TMP]], [[IF_THEN]] ] +; CHECK-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[IDX_EXT]], [[IF_THEN]] ] +; CHECK-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32 +; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]] +; CHECK-NEXT: ret i32 [[RES]] ; entry: br i1 %cond, label %if.then, label %if.end @@ -402,3 +341,6 @@ if.end: %res = load i32, ptr %arrayidx2, align 4 ret i32 %res } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll b/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll index cb05a8ed384ce..86c7f44f170e7 100644 --- a/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll +++ b/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll @@ -7,29 +7,17 @@ ; Test that phi translation is able to hoist a load whose address ; depends on an add also being hoisted. define double @phi_translation_hoists_add(ptr %a, i64 %idx) { -; PT-ON-MDEP-LABEL: @phi_translation_hoists_add( -; PT-ON-MDEP-NEXT: entry: -; PT-ON-MDEP-NEXT: [[ADD_PHI_TRANS_INSERT:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1 -; PT-ON-MDEP-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD_PHI_TRANS_INSERT]] -; PT-ON-MDEP-NEXT: [[LOAD_PRE:%.*]] = load double, ptr [[GEP_PHI_TRANS_INSERT]], align 8 -; PT-ON-MDEP-NEXT: br label [[FOR_BODY:%.*]] -; PT-ON-MDEP: for.body: -; PT-ON-MDEP-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD_PRE]], 1.000000e+00 -; PT-ON-MDEP-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]] -; PT-ON-MDEP: exit: -; PT-ON-MDEP-NEXT: ret double [[LOAD_PRE]] -; -; PT-ON-MSSA-LABEL: @phi_translation_hoists_add( -; PT-ON-MSSA-NEXT: entry: -; PT-ON-MSSA-NEXT: br label [[FOR_BODY:%.*]] -; PT-ON-MSSA: for.body: -; PT-ON-MSSA-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1 -; PT-ON-MSSA-NEXT: [[GEP:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD]] -; PT-ON-MSSA-NEXT: [[LOAD:%.*]] = load double, ptr [[GEP]], align 8 -; PT-ON-MSSA-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD]], 1.000000e+00 -; PT-ON-MSSA-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]] -; PT-ON-MSSA: exit: -; PT-ON-MSSA-NEXT: ret double [[LOAD]] +; ADD-TRANS-ON-LABEL: @phi_translation_hoists_add( +; ADD-TRANS-ON-NEXT: entry: +; ADD-TRANS-ON-NEXT: [[ADD_PHI_TRANS_INSERT:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1 +; ADD-TRANS-ON-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD_PHI_TRANS_INSERT]] +; ADD-TRANS-ON-NEXT: [[LOAD_PRE:%.*]] = load double, ptr [[GEP_PHI_TRANS_INSERT]], align 8 +; ADD-TRANS-ON-NEXT: br label [[FOR_BODY:%.*]] +; ADD-TRANS-ON: for.body: +; ADD-TRANS-ON-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD_PRE]], 1.000000e+00 +; ADD-TRANS-ON-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]] +; ADD-TRANS-ON: exit: +; ADD-TRANS-ON-NEXT: ret double [[LOAD_PRE]] ; ; ADD-TRANS-OFF-LABEL: @phi_translation_hoists_add( ; ADD-TRANS-OFF-NEXT: entry: @@ -57,7 +45,8 @@ exit: ret double %load } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; ADD-TRANS-ON: {{.*}} ; CHECK: {{.*}} ; PT-OFF-MDEP: {{.*}} ; PT-OFF-MSSA: {{.*}} +; PT-ON-MDEP: {{.*}} +; PT-ON-MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate.ll b/llvm/test/Transforms/GVN/PRE/phi-translate.ll index 084c449879b16..1915244e9490e 100644 --- a/llvm/test/Transforms/GVN/PRE/phi-translate.ll +++ b/llvm/test/Transforms/GVN/PRE/phi-translate.ll @@ -8,45 +8,26 @@ target datalayout = "e-p:64:64:64" @G = external global [100 x i32] define i32 @foo(i32 %x, i32 %z) !dbg !6 { -; MDEP-LABEL: define i32 @foo( -; MDEP-SAME: i32 [[X:%.*]], i32 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[Z]], 0, !dbg [[DBG8:![0-9]+]] -; MDEP-NEXT: br i1 [[TOBOOL]], label %[[ENTRY_END_CRIT_EDGE:.*]], label %[[THEN:.*]], !dbg [[DBG8]] -; MDEP: [[ENTRY_END_CRIT_EDGE]]: -; MDEP-NEXT: [[J_PHI_TRANS_INSERT:%.*]] = sext i32 [[X]] to i64 -; MDEP-NEXT: [[Q_PHI_TRANS_INSERT:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PHI_TRANS_INSERT]] -; MDEP-NEXT: [[N_PRE:%.*]] = load i32, ptr [[Q_PHI_TRANS_INSERT]], align 4, !dbg [[DBG9:![0-9]+]] -; MDEP-NEXT: br label %[[END:.*]], !dbg [[DBG8]] -; MDEP: [[THEN]]: -; MDEP-NEXT: [[I:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG10:![0-9]+]] -; MDEP-NEXT: [[P:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[I]], !dbg [[DBG10]] -; MDEP-NEXT: store i32 [[Z]], ptr [[P]], align 4, !dbg [[DBG10]] -; MDEP-NEXT: br label %[[END]], !dbg [[DBG10]] -; MDEP: [[END]]: -; MDEP-NEXT: [[J_PRE_PHI:%.*]] = phi i64 [ [[J_PHI_TRANS_INSERT]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[I]], %[[THEN]] ], !dbg [[DBG11:![0-9]+]] -; MDEP-NEXT: [[N:%.*]] = phi i32 [ [[N_PRE]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[Z]], %[[THEN]] ], !dbg [[DBG9]] -; MDEP-NEXT: [[Q:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PRE_PHI]], !dbg [[DBG12:![0-9]+]] -; MDEP-NEXT: ret i32 [[N]], !dbg [[DBG9]] -; -; MSSA-LABEL: define i32 @foo( -; MSSA-SAME: i32 [[X:%.*]], i32 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[Z]], 0, !dbg [[DBG8:![0-9]+]] -; MSSA-NEXT: br i1 [[TOBOOL]], label %[[ENTRY_END_CRIT_EDGE:.*]], label %[[THEN:.*]], !dbg [[DBG8]] -; MSSA: [[ENTRY_END_CRIT_EDGE]]: -; MSSA-NEXT: [[DOTPRE:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG9:![0-9]+]] -; MSSA-NEXT: br label %[[END:.*]], !dbg [[DBG8]] -; MSSA: [[THEN]]: -; MSSA-NEXT: [[I:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG10:![0-9]+]] -; MSSA-NEXT: [[P:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[I]], !dbg [[DBG10]] -; MSSA-NEXT: store i32 [[Z]], ptr [[P]], align 4, !dbg [[DBG10]] -; MSSA-NEXT: br label %[[END]], !dbg [[DBG10]] -; MSSA: [[END]]: -; MSSA-NEXT: [[J_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[I]], %[[THEN]] ], !dbg [[DBG9]] -; MSSA-NEXT: [[Q:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PRE_PHI]], !dbg [[DBG11:![0-9]+]] -; MSSA-NEXT: [[N:%.*]] = load i32, ptr [[Q]], align 4, !dbg [[DBG12:![0-9]+]] -; MSSA-NEXT: ret i32 [[N]], !dbg [[DBG12]] +; CHECK-LABEL: define i32 @foo( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[Z]], 0, !dbg [[DBG8:![0-9]+]] +; CHECK-NEXT: br i1 [[TOBOOL]], label %[[ENTRY_END_CRIT_EDGE:.*]], label %[[THEN:.*]], !dbg [[DBG8]] +; CHECK: [[ENTRY_END_CRIT_EDGE]]: +; CHECK-NEXT: [[J_PHI_TRANS_INSERT:%.*]] = sext i32 [[X]] to i64 +; CHECK-NEXT: [[Q_PHI_TRANS_INSERT:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PHI_TRANS_INSERT]] +; CHECK-NEXT: [[N_PRE:%.*]] = load i32, ptr [[Q_PHI_TRANS_INSERT]], align 4, !dbg [[DBG9:![0-9]+]] +; CHECK-NEXT: br label %[[END:.*]], !dbg [[DBG8]] +; CHECK: [[THEN]]: +; CHECK-NEXT: [[I:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG10:![0-9]+]] +; CHECK-NEXT: [[P:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[I]], !dbg [[DBG10]] +; CHECK-NEXT: store i32 [[Z]], ptr [[P]], align 4, !dbg [[DBG10]] +; CHECK-NEXT: br label %[[END]], !dbg [[DBG10]] +; CHECK: [[END]]: +; CHECK-NEXT: [[J_PRE_PHI:%.*]] = phi i64 [ [[J_PHI_TRANS_INSERT]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[I]], %[[THEN]] ], !dbg [[DBG11:![0-9]+]] +; CHECK-NEXT: [[N:%.*]] = phi i32 [ [[N_PRE]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[Z]], %[[THEN]] ], !dbg [[DBG9]] +; CHECK-NEXT: [[Q:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PRE_PHI]], !dbg [[DBG12:![0-9]+]] +; CHECK-NEXT: ret i32 [[N]], !dbg [[DBG9]] ; entry: %tobool = icmp eq i32 %z, 0, !dbg !7 @@ -85,27 +66,17 @@ end: isOptimized: true, flags: "-O2", splitDebugFilename: "abc.debug", emissionKind: 2) ;. -; MDEP: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META4:![0-9]+]], producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) -; MDEP: [[META4]] = !DIFile(filename: "{{.*}}a.cc", directory: {{.*}}) -; MDEP: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META4]], file: [[META4]], line: 42, type: [[META6:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META3]], retainedNodes: [[META7:![0-9]+]]) -; MDEP: [[META6]] = !DISubroutineType(types: [[META7]]) -; MDEP: [[META7]] = !{} -; MDEP: [[DBG8]] = !DILocation(line: 43, column: 1, scope: [[DBG5]]) -; MDEP: [[DBG9]] = !DILocation(line: 47, column: 1, scope: [[DBG5]]) -; MDEP: [[DBG10]] = !DILocation(line: 44, column: 1, scope: [[DBG5]]) -; MDEP: [[DBG11]] = !DILocation(line: 45, column: 1, scope: [[DBG5]]) -; MDEP: [[DBG12]] = !DILocation(line: 46, column: 1, scope: [[DBG5]]) -;. -; MSSA: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META4:![0-9]+]], producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) -; MSSA: [[META4]] = !DIFile(filename: "{{.*}}a.cc", directory: {{.*}}) -; MSSA: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META4]], file: [[META4]], line: 42, type: [[META6:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META3]], retainedNodes: [[META7:![0-9]+]]) -; MSSA: [[META6]] = !DISubroutineType(types: [[META7]]) -; MSSA: [[META7]] = !{} -; MSSA: [[DBG8]] = !DILocation(line: 43, column: 1, scope: [[DBG5]]) -; MSSA: [[DBG9]] = !DILocation(line: 45, column: 1, scope: [[DBG5]]) -; MSSA: [[DBG10]] = !DILocation(line: 44, column: 1, scope: [[DBG5]]) -; MSSA: [[DBG11]] = !DILocation(line: 46, column: 1, scope: [[DBG5]]) -; MSSA: [[DBG12]] = !DILocation(line: 47, column: 1, scope: [[DBG5]]) +; CHECK: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META4:![0-9]+]], producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) +; CHECK: [[META4]] = !DIFile(filename: "{{.*}}a.cc", directory: {{.*}}) +; CHECK: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META4]], file: [[META4]], line: 42, type: [[META6:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META3]], retainedNodes: [[META7:![0-9]+]]) +; CHECK: [[META6]] = !DISubroutineType(types: [[META7]]) +; CHECK: [[META7]] = !{} +; CHECK: [[DBG8]] = !DILocation(line: 43, column: 1, scope: [[DBG5]]) +; CHECK: [[DBG9]] = !DILocation(line: 47, column: 1, scope: [[DBG5]]) +; CHECK: [[DBG10]] = !DILocation(line: 44, column: 1, scope: [[DBG5]]) +; CHECK: [[DBG11]] = !DILocation(line: 45, column: 1, scope: [[DBG5]]) +; CHECK: [[DBG12]] = !DILocation(line: 46, column: 1, scope: [[DBG5]]) ;. ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-after-rle.ll b/llvm/test/Transforms/GVN/PRE/pre-after-rle.ll index b18ad5dae4633..14e2de21de497 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-after-rle.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-after-rle.ll @@ -1,52 +1,32 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt -passes='require,gvn' -S < %s | FileCheck %s --check-prefixes=CHECK-MEMDEP -; RUN: opt -passes='require,gvn' -S < %s | FileCheck %s --check-prefixes=CHECK-MEMSSA +; RUN: opt -passes='require,gvn' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MEMDEP +; RUN: opt -passes='require,gvn' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MEMSSA declare noalias ptr @malloc(i64) ; Detecting that %s is fully redundant should let us detect that %w is partially ; redundant. define void @fn1(ptr noalias %start, ptr %width, i32 %h) { -; CHECK-MEMDEP-LABEL: define void @fn1( -; CHECK-MEMDEP-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]]) { -; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]] -; CHECK-MEMDEP-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) -; CHECK-MEMDEP-NEXT: store ptr [[CALL]], ptr [[START]], align 8 -; CHECK-MEMDEP-NEXT: br label %[[PREHEADER:.*]] -; CHECK-MEMDEP: [[PREHEADER]]: -; CHECK-MEMDEP-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] -; CHECK-MEMDEP-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]] -; CHECK-MEMDEP: [[PREHEADER_BODY_CRIT_EDGE]]: -; CHECK-MEMDEP-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 8 -; CHECK-MEMDEP-NEXT: br label %[[BODY:.*]] -; CHECK-MEMDEP: [[BODY]]: -; CHECK-MEMDEP-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] -; CHECK-MEMDEP-NEXT: store i32 0, ptr [[CALL]], align 4 -; CHECK-MEMDEP-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 -; CHECK-MEMDEP-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] -; CHECK-MEMDEP-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] -; CHECK-MEMDEP: [[EXIT]]: -; CHECK-MEMDEP-NEXT: ret void -; -; CHECK-MEMSSA-LABEL: define void @fn1( -; CHECK-MEMSSA-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]]) { -; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]] -; CHECK-MEMSSA-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) -; CHECK-MEMSSA-NEXT: store ptr [[CALL]], ptr [[START]], align 8 -; CHECK-MEMSSA-NEXT: br label %[[PREHEADER:.*]] -; CHECK-MEMSSA: [[PREHEADER]]: -; CHECK-MEMSSA-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] -; CHECK-MEMSSA-NEXT: br i1 [[CMP]], label %[[BODY:.*]], label %[[EXIT:.*]] -; CHECK-MEMSSA: [[BODY]]: -; CHECK-MEMSSA-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] -; CHECK-MEMSSA-NEXT: [[S:%.*]] = load ptr, ptr [[START]], align 8 -; CHECK-MEMSSA-NEXT: store i32 0, ptr [[S]], align 4 -; CHECK-MEMSSA-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 -; CHECK-MEMSSA-NEXT: [[W:%.*]] = load i32, ptr [[WIDTH]], align 8 -; CHECK-MEMSSA-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W]] -; CHECK-MEMSSA-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] -; CHECK-MEMSSA: [[EXIT]]: -; CHECK-MEMSSA-NEXT: ret void +; CHECK-LABEL: define void @fn1( +; CHECK-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) +; CHECK-NEXT: store ptr [[CALL]], ptr [[START]], align 8 +; CHECK-NEXT: br label %[[PREHEADER:.*]] +; CHECK: [[PREHEADER]]: +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] +; CHECK-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]] +; CHECK: [[PREHEADER_BODY_CRIT_EDGE]]: +; CHECK-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 8 +; CHECK-NEXT: br label %[[BODY:.*]] +; CHECK: [[BODY]]: +; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] +; CHECK-NEXT: store i32 0, ptr [[CALL]], align 4 +; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 +; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] +; CHECK-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void ; entry: %call = tail call noalias ptr @malloc(i64 1024) @@ -74,61 +54,34 @@ exit: ; %w is partially redundant requires alias analysis that can analyze those ; values. define void @fn2(ptr noalias %start, ptr %width, i32 %h, i32 %arg) { -; CHECK-MEMDEP-LABEL: define void @fn2( -; CHECK-MEMDEP-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]], i32 [[ARG:%.*]]) { -; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]] -; CHECK-MEMDEP-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) -; CHECK-MEMDEP-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG]], 0 -; CHECK-MEMDEP-NEXT: br i1 [[CMP1]], label %[[IF:.*]], label %[[ELSE:.*]] -; CHECK-MEMDEP: [[IF]]: -; CHECK-MEMDEP-NEXT: store ptr [[CALL]], ptr [[START]], align 8 -; CHECK-MEMDEP-NEXT: br label %[[PREHEADER:.*]] -; CHECK-MEMDEP: [[ELSE]]: -; CHECK-MEMDEP-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]] -; CHECK-MEMDEP-NEXT: store ptr [[GEP]], ptr [[START]], align 8 -; CHECK-MEMDEP-NEXT: br label %[[PREHEADER]] -; CHECK-MEMDEP: [[PREHEADER]]: -; CHECK-MEMDEP-NEXT: [[S:%.*]] = phi ptr [ [[S]], %[[BODY:.*]] ], [ [[GEP]], %[[ELSE]] ], [ [[CALL]], %[[IF]] ] -; CHECK-MEMDEP-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] -; CHECK-MEMDEP-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]] -; CHECK-MEMDEP: [[PREHEADER_BODY_CRIT_EDGE]]: -; CHECK-MEMDEP-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 8 -; CHECK-MEMDEP-NEXT: br label %[[BODY]] -; CHECK-MEMDEP: [[BODY]]: -; CHECK-MEMDEP-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] -; CHECK-MEMDEP-NEXT: store i32 0, ptr [[S]], align 4 -; CHECK-MEMDEP-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 -; CHECK-MEMDEP-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] -; CHECK-MEMDEP-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] -; CHECK-MEMDEP: [[EXIT]]: -; CHECK-MEMDEP-NEXT: ret void -; -; CHECK-MEMSSA-LABEL: define void @fn2( -; CHECK-MEMSSA-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]], i32 [[ARG:%.*]]) { -; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]] -; CHECK-MEMSSA-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) -; CHECK-MEMSSA-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG]], 0 -; CHECK-MEMSSA-NEXT: br i1 [[CMP1]], label %[[IF:.*]], label %[[ELSE:.*]] -; CHECK-MEMSSA: [[IF]]: -; CHECK-MEMSSA-NEXT: store ptr [[CALL]], ptr [[START]], align 8 -; CHECK-MEMSSA-NEXT: br label %[[PREHEADER:.*]] -; CHECK-MEMSSA: [[ELSE]]: -; CHECK-MEMSSA-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]] -; CHECK-MEMSSA-NEXT: store ptr [[GEP]], ptr [[START]], align 8 -; CHECK-MEMSSA-NEXT: br label %[[PREHEADER]] -; CHECK-MEMSSA: [[PREHEADER]]: -; CHECK-MEMSSA-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] -; CHECK-MEMSSA-NEXT: br i1 [[CMP]], label %[[BODY:.*]], label %[[EXIT:.*]] -; CHECK-MEMSSA: [[BODY]]: -; CHECK-MEMSSA-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] -; CHECK-MEMSSA-NEXT: [[S:%.*]] = load ptr, ptr [[START]], align 8 -; CHECK-MEMSSA-NEXT: store i32 0, ptr [[S]], align 4 -; CHECK-MEMSSA-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 -; CHECK-MEMSSA-NEXT: [[W:%.*]] = load i32, ptr [[WIDTH]], align 8 -; CHECK-MEMSSA-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W]] -; CHECK-MEMSSA-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] -; CHECK-MEMSSA: [[EXIT]]: -; CHECK-MEMSSA-NEXT: ret void +; CHECK-LABEL: define void @fn2( +; CHECK-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]], i32 [[ARG:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG]], 0 +; CHECK-NEXT: br i1 [[CMP1]], label %[[IF:.*]], label %[[ELSE:.*]] +; CHECK: [[IF]]: +; CHECK-NEXT: store ptr [[CALL]], ptr [[START]], align 8 +; CHECK-NEXT: br label %[[PREHEADER:.*]] +; CHECK: [[ELSE]]: +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]] +; CHECK-NEXT: store ptr [[GEP]], ptr [[START]], align 8 +; CHECK-NEXT: br label %[[PREHEADER]] +; CHECK: [[PREHEADER]]: +; CHECK-NEXT: [[S:%.*]] = phi ptr [ [[S]], %[[BODY:.*]] ], [ [[GEP]], %[[ELSE]] ], [ [[CALL]], %[[IF]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]] +; CHECK-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]] +; CHECK: [[PREHEADER_BODY_CRIT_EDGE]]: +; CHECK-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 8 +; CHECK-NEXT: br label %[[BODY]] +; CHECK: [[BODY]]: +; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ] +; CHECK-NEXT: store i32 0, ptr [[S]], align 4 +; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 +; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] +; CHECK-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void ; entry: %call = tail call noalias ptr @malloc(i64 1024) @@ -160,3 +113,6 @@ body: exit: ret void } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK-MEMDEP: {{.*}} +; CHECK-MEMSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll b/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll index 60611a032ded5..5b6cb469870ac 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll @@ -103,45 +103,25 @@ exit: } define i32 @test_03(ptr %p) { -; MDEP-LABEL: @test_03( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 -; MDEP-NEXT: br label [[LOOP:%.*]] -; MDEP: loop: -; MDEP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; MDEP-NEXT: [[COND:%.*]] = icmp ult i32 [[X_PRE]], 100 -; MDEP-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]] -; MDEP: hot_path: -; MDEP-NEXT: br label [[BACKEDGE]] -; MDEP: cold_path: -; MDEP-NEXT: call void @no_side_effect() -; MDEP-NEXT: br label [[BACKEDGE]] -; MDEP: backedge: -; MDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X_PRE]] -; MDEP-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000 -; MDEP-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] -; MDEP: exit: -; MDEP-NEXT: ret i32 [[X_PRE]] -; -; MSSA-LABEL: @test_03( -; MSSA-NEXT: entry: -; MSSA-NEXT: br label [[LOOP:%.*]] -; MSSA: loop: -; MSSA-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; MSSA-NEXT: [[X:%.*]] = load i32, ptr [[P:%.*]], align 4 -; MSSA-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], 100 -; MSSA-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]] -; MSSA: hot_path: -; MSSA-NEXT: br label [[BACKEDGE]] -; MSSA: cold_path: -; MSSA-NEXT: call void @no_side_effect() -; MSSA-NEXT: br label [[BACKEDGE]] -; MSSA: backedge: -; MSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X]] -; MSSA-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000 -; MSSA-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] -; MSSA: exit: -; MSSA-NEXT: ret i32 [[X]] +; CHECK-LABEL: @test_03( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X_PRE]], 100 +; CHECK-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]] +; CHECK: hot_path: +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: cold_path: +; CHECK-NEXT: call void @no_side_effect() +; CHECK-NEXT: br label [[BACKEDGE]] +; CHECK: backedge: +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X_PRE]] +; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000 +; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret i32 [[X_PRE]] ; entry: br label %loop @@ -167,3 +147,6 @@ backedge: exit: ret i32 %x } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll b/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll index f961f23d6b10e..5ddbd8aa694e5 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll @@ -13,79 +13,41 @@ @h = global %struct.a zeroinitializer, align 1 define void @withdbg() { -; MDEP-LABEL: define void @withdbg() { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 -; MDEP-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1 -; MDEP-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1 -; MDEP-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] -; MDEP: [[LOR_RHS]]: -; MDEP-NEXT: #dbg_declare(ptr undef, [[META4:![0-9]+]], !DIExpression(), [[META14:![0-9]+]]) -; MDEP-NEXT: #dbg_declare(ptr undef, [[META10:![0-9]+]], !DIExpression(), [[META14]]) -; MDEP-NEXT: #dbg_declare(ptr undef, [[META11:![0-9]+]], !DIExpression(), [[META14]]) -; MDEP-NEXT: #dbg_declare(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META14]]) -; MDEP-NEXT: #dbg_declare(ptr undef, [[META13:![0-9]+]], !DIExpression(), [[META14]]) -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: br label %[[LOR_END]] -; MDEP: [[LOR_END]]: -; MDEP-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32 -; MDEP-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: define void @withdbg() { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 -; MSSA-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] -; MSSA: [[LOR_RHS]]: -; MSSA-NEXT: #dbg_declare(ptr undef, [[META4:![0-9]+]], !DIExpression(), [[META14:![0-9]+]]) -; MSSA-NEXT: #dbg_declare(ptr undef, [[META10:![0-9]+]], !DIExpression(), [[META14]]) -; MSSA-NEXT: #dbg_declare(ptr undef, [[META11:![0-9]+]], !DIExpression(), [[META14]]) -; MSSA-NEXT: #dbg_declare(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META14]]) -; MSSA-NEXT: #dbg_declare(ptr undef, [[META13:![0-9]+]], !DIExpression(), [[META14]]) -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[FVALUE:%.*]] = load i16, ptr @f, align 1 -; MSSA-NEXT: [[MVALUE:%.*]] = load ptr, ptr @m, align 1 -; MSSA-NEXT: br label %[[LOR_END]] -; MSSA: [[LOR_END]]: -; MSSA-NEXT: [[TMP11:%.*]] = load i16, ptr @f, align 1 -; MSSA-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11]] to i32 -; MSSA-NEXT: [[TMP12:%.*]] = load ptr, ptr @m, align 1 -; MSSA-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12]], align 1 -; MSSA-NEXT: ret void +; CHECK-LABEL: define void @withdbg() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 +; CHECK-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1 +; CHECK-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1 +; CHECK-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] +; CHECK: [[LOR_RHS]]: +; CHECK-NEXT: #dbg_declare(ptr undef, [[META4:![0-9]+]], !DIExpression(), [[META14:![0-9]+]]) +; CHECK-NEXT: #dbg_declare(ptr undef, [[META10:![0-9]+]], !DIExpression(), [[META14]]) +; CHECK-NEXT: #dbg_declare(ptr undef, [[META11:![0-9]+]], !DIExpression(), [[META14]]) +; CHECK-NEXT: #dbg_declare(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META14]]) +; CHECK-NEXT: #dbg_declare(ptr undef, [[META13:![0-9]+]], !DIExpression(), [[META14]]) +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: br label %[[LOR_END]] +; CHECK: [[LOR_END]]: +; CHECK-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32 +; CHECK-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1 +; CHECK-NEXT: ret void ; entry: @@ -130,69 +92,36 @@ lor.end: ; preds = %lor.rhs, %entry } define void @lessdbg() { -; MDEP-LABEL: define void @lessdbg() { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 -; MDEP-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1 -; MDEP-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1 -; MDEP-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] -; MDEP: [[LOR_RHS]]: -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 -; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MDEP-NEXT: br label %[[LOR_END]] -; MDEP: [[LOR_END]]: -; MDEP-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32 -; MDEP-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: define void @lessdbg() { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 -; MSSA-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] -; MSSA: [[LOR_RHS]]: -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 -; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 -; MSSA-NEXT: [[FVALUE:%.*]] = load i16, ptr @f, align 1 -; MSSA-NEXT: [[MVALUE:%.*]] = load ptr, ptr @m, align 1 -; MSSA-NEXT: br label %[[LOR_END]] -; MSSA: [[LOR_END]]: -; MSSA-NEXT: [[TMP11:%.*]] = load i16, ptr @f, align 1 -; MSSA-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11]] to i32 -; MSSA-NEXT: [[TMP12:%.*]] = load ptr, ptr @m, align 1 -; MSSA-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12]], align 1 -; MSSA-NEXT: ret void +; CHECK-LABEL: define void @lessdbg() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1 +; CHECK-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1 +; CHECK-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1 +; CHECK-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]] +; CHECK: [[LOR_RHS]]: +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1 +; CHECK-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1 +; CHECK-NEXT: br label %[[LOR_END]] +; CHECK: [[LOR_END]]: +; CHECK-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32 +; CHECK-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1 +; CHECK-NEXT: ret void ; entry: @@ -253,33 +182,20 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) !49 = !DILocalVariable(name: "d", scope: !41, file: !1, line: 15, type: !5) !50 = !DILocalVariable(name: "u", scope: !41, file: !1, line: 16, type: !5) ;. -; MDEP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -; MDEP: [[META1]] = !DIFile(filename: "{{.*}}bbi-78272.c", directory: {{.*}}) -; MDEP: [[META4]] = !DILocalVariable(name: "t", scope: [[META5:![0-9]+]], file: [[META1]], line: 15, type: [[META8:![0-9]+]]) -; MDEP: [[META5]] = distinct !DISubprogram(name: "x", scope: [[META1]], file: [[META1]], line: 14, type: [[META6:![0-9]+]], scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META9:![0-9]+]]) -; MDEP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]]) -; MDEP: [[META7]] = !{[[META8]]} -; MDEP: [[META8]] = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed) -; MDEP: [[META9]] = !{[[META4]], [[META10]], [[META11]], [[META12]], [[META13]]} -; MDEP: [[META10]] = !DILocalVariable(name: "c", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MDEP: [[META11]] = !DILocalVariable(name: "v", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MDEP: [[META12]] = !DILocalVariable(name: "d", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MDEP: [[META13]] = !DILocalVariable(name: "u", scope: [[META5]], file: [[META1]], line: 16, type: [[META8]]) -; MDEP: [[META14]] = !DILocation(line: 15, column: 7, scope: [[META5]]) -;. -; MSSA: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -; MSSA: [[META1]] = !DIFile(filename: "{{.*}}bbi-78272.c", directory: {{.*}}) -; MSSA: [[META4]] = !DILocalVariable(name: "t", scope: [[META5:![0-9]+]], file: [[META1]], line: 15, type: [[META8:![0-9]+]]) -; MSSA: [[META5]] = distinct !DISubprogram(name: "x", scope: [[META1]], file: [[META1]], line: 14, type: [[META6:![0-9]+]], scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META9:![0-9]+]]) -; MSSA: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]]) -; MSSA: [[META7]] = !{[[META8]]} -; MSSA: [[META8]] = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed) -; MSSA: [[META9]] = !{[[META4]], [[META10]], [[META11]], [[META12]], [[META13]]} -; MSSA: [[META10]] = !DILocalVariable(name: "c", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MSSA: [[META11]] = !DILocalVariable(name: "v", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MSSA: [[META12]] = !DILocalVariable(name: "d", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) -; MSSA: [[META13]] = !DILocalVariable(name: "u", scope: [[META5]], file: [[META1]], line: 16, type: [[META8]]) -; MSSA: [[META14]] = !DILocation(line: 15, column: 7, scope: [[META5]]) +; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +; CHECK: [[META1]] = !DIFile(filename: "{{.*}}bbi-78272.c", directory: {{.*}}) +; CHECK: [[META4]] = !DILocalVariable(name: "t", scope: [[META5:![0-9]+]], file: [[META1]], line: 15, type: [[META8:![0-9]+]]) +; CHECK: [[META5]] = distinct !DISubprogram(name: "x", scope: [[META1]], file: [[META1]], line: 14, type: [[META6:![0-9]+]], scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META9:![0-9]+]]) +; CHECK: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]]) +; CHECK: [[META7]] = !{[[META8]]} +; CHECK: [[META8]] = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed) +; CHECK: [[META9]] = !{[[META4]], [[META10]], [[META11]], [[META12]], [[META13]]} +; CHECK: [[META10]] = !DILocalVariable(name: "c", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) +; CHECK: [[META11]] = !DILocalVariable(name: "v", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) +; CHECK: [[META12]] = !DILocalVariable(name: "d", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]]) +; CHECK: [[META13]] = !DILocalVariable(name: "u", scope: [[META5]], file: [[META1]], line: 16, type: [[META8]]) +; CHECK: [[META14]] = !DILocation(line: 15, column: 7, scope: [[META5]]) ;. ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll b/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll index ca1852f49bf31..d7f5c46198645 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll @@ -95,36 +95,21 @@ block4: ; Guard in load's block that is below the load should not prohibit the PRE. define i32 @test_guard_02(ptr %p, ptr %q, i1 %C, i1 %G) { -; MDEP-LABEL: define i32 @test_guard_02( -; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) { -; MDEP-NEXT: [[BLOCK1:.*:]] -; MDEP-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MDEP: [[BLOCK2]]: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q]], align 4 -; MDEP-NEXT: br label %[[BLOCK4:.*]] -; MDEP: [[BLOCK3]]: -; MDEP-NEXT: store i32 0, ptr [[P]], align 4 -; MDEP-NEXT: br label %[[BLOCK4]] -; MDEP: [[BLOCK4]]: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[PRE_PRE]], %[[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ] -; MDEP-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ] -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: define i32 @test_guard_02( -; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) { -; MSSA-NEXT: [[BLOCK1:.*:]] -; MSSA-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MSSA: [[BLOCK2]]: -; MSSA-NEXT: br label %[[BLOCK4:.*]] -; MSSA: [[BLOCK3]]: -; MSSA-NEXT: store i32 0, ptr [[P]], align 4 -; MSSA-NEXT: br label %[[BLOCK4]] -; MSSA: [[BLOCK4]]: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ] -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4 -; MSSA-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ] -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: define i32 @test_guard_02( +; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) { +; CHECK-NEXT: [[BLOCK1:.*:]] +; CHECK-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] +; CHECK: [[BLOCK2]]: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q]], align 4 +; CHECK-NEXT: br label %[[BLOCK4:.*]] +; CHECK: [[BLOCK3]]: +; CHECK-NEXT: store i32 0, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[BLOCK4]] +; CHECK: [[BLOCK4]]: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[PRE_PRE]], %[[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ] +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -187,3 +172,6 @@ block5: %PRE = load i32, ptr %P2 ret i32 %PRE } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll b/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll index 17fbc0e38ec66..615e2b802bd5e 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll @@ -13,25 +13,15 @@ declare i32 @foo(i32 %arg) #0 define hidden void @test_01(i32 %x, i32 %y) { ; c2 only throws if c1 throws, so it can be safely removed and then PRE can ; hoist the load out of loop. -; MDEP-LABEL: define hidden void @test_01( -; MDEP-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) -; MDEP-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8 -; MDEP-NEXT: br label %[[LOOP:.*]] -; MDEP: [[LOOP]]: -; MDEP-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL_PRE]]) -; MDEP-NEXT: br label %[[LOOP]] -; -; MSSA-LABEL: define hidden void @test_01( -; MSSA-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) -; MSSA-NEXT: br label %[[LOOP:.*]] -; MSSA: [[LOOP]]: -; MSSA-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8 -; MSSA-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL]]) -; MSSA-NEXT: br label %[[LOOP]] +; CHECK-LABEL: define hidden void @test_01( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) +; CHECK-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8 +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL_PRE]]) +; CHECK-NEXT: br label %[[LOOP]] ; entry: @@ -73,28 +63,16 @@ loop: define hidden void @test_03(i32 %x, i32 %y) { ; PRE of load is allowed because c2 only throws if c1 throws. c3 should ; not be eliminated. c4 is eliminated because it only throws if c3 throws. -; MDEP-LABEL: define hidden void @test_03( -; MDEP-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) -; MDEP-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8 -; MDEP-NEXT: br label %[[LOOP:.*]] -; MDEP: [[LOOP]]: -; MDEP-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]]) -; MDEP-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL_PRE]]) -; MDEP-NEXT: br label %[[LOOP]] -; -; MSSA-LABEL: define hidden void @test_03( -; MSSA-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) -; MSSA-NEXT: br label %[[LOOP:.*]] -; MSSA: [[LOOP]]: -; MSSA-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8 -; MSSA-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]]) -; MSSA-NEXT: [[VAL2:%.*]] = load i32, ptr null, align 8 -; MSSA-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL]]) -; MSSA-NEXT: br label %[[LOOP]] +; CHECK-LABEL: define hidden void @test_03( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]]) +; CHECK-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8 +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]]) +; CHECK-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL_PRE]]) +; CHECK-NEXT: br label %[[LOOP]] ; entry: @@ -139,3 +117,6 @@ loop: } attributes #0 = { readnone } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-load.ll b/llvm/test/Transforms/GVN/PRE/pre-load.ll index afa13549db458..2cdec2f2120af 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-load.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-load.ll @@ -5,30 +5,18 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" define i32 @test1(ptr %p, i1 %C) { -; MDEP-LABEL: @test1( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: store i32 0, ptr [[P]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test1( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test1( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: store i32 0, ptr [[P]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -47,32 +35,19 @@ block4: ; This is a simple phi translation case. define i32 @test2(ptr %p, ptr %q, i1 %C) { -; MDEP-LABEL: @test2( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q:%.*]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: store i32 0, ptr [[P:%.*]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test2( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q:%.*]], [[BLOCK2]] ] -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test2( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q:%.*]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -92,40 +67,23 @@ block4: ; This is a PRE case that requires phi translation through a GEP. define i32 @test3(ptr %p, ptr %q, ptr %Hack, i1 %C) { -; MDEP-LABEL: @test3( -; MDEP-NEXT: block1: -; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[B]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MDEP-NEXT: store i32 0, ptr [[A]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test3( -; MSSA-NEXT: block1: -; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MSSA-NEXT: store i32 0, ptr [[A]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test3( +; CHECK-NEXT: block1: +; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 +; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[B]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 +; CHECK-NEXT: store i32 0, ptr [[A]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] +; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 +; CHECK-NEXT: ret i32 [[PRE]] ; block1: %B = getelementptr i32, ptr %q, i32 1 @@ -150,41 +108,24 @@ block4: ;; Here the loaded address is available, but the computation is in 'block3' ;; which does not dominate 'block2'. define i32 @test4(ptr %p, ptr %q, ptr %Hack, i1 %C) { -; MDEP-LABEL: @test4( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1 -; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MDEP-NEXT: store i32 0, ptr [[A]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test4( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MSSA-NEXT: store i32 0, ptr [[A]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test4( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1 +; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 +; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 +; CHECK-NEXT: store i32 0, ptr [[A]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] +; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -209,41 +150,24 @@ block4: ; Same as test4, with a nuw flag on the GEP. define i32 @test4_nuw(ptr %p, ptr %q, ptr %Hack, i1 %C) { -; MDEP-LABEL: @test4_nuw( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr nuw i32, ptr [[Q:%.*]], i32 1 -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1 -; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MDEP-NEXT: store i32 0, ptr [[A]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MDEP-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1 -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test4_nuw( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 -; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MSSA-NEXT: store i32 0, ptr [[A]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MSSA-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1 -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test4_nuw( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr nuw i32, ptr [[Q:%.*]], i32 1 +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1 +; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8 +; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 +; CHECK-NEXT: store i32 0, ptr [[A]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] +; CHECK-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1 +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -273,50 +197,28 @@ block4: ;} define void @test5(i32 %N, ptr nocapture %G) nounwind ssp { -; MDEP-LABEL: @test5( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 -; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP3:%.*]], [[BB]] ] -; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] -; MDEP-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 -; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]] -; MDEP-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] -; MDEP-NEXT: [[TMP3]] = load double, ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] -; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8 -; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] -; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test5( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] -; MSSA-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 -; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP6]] -; MSSA-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] -; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP7]], align 8 -; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] -; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8 -; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] -; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test5( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP3:%.*]], [[BB]] ] +; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] +; CHECK-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]] +; CHECK-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] +; CHECK-NEXT: [[TMP3]] = load double, ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] +; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: %0 = add i32 %N, -1 @@ -353,50 +255,28 @@ return: ;} define void @test6(i32 %N, ptr nocapture %G) nounwind ssp { -; MDEP-LABEL: @test6( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 -; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] -; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] -; MDEP-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 -; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]] -; MDEP-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] -; MDEP-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]] -; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] -; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test6( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 -; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] -; MSSA-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 -; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP6]] -; MSSA-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] -; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP7]], align 8 -; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] -; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] -; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] +; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] +; CHECK-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1 +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]] +; CHECK-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] +; CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]] +; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: %0 = add i32 %N, -1 @@ -435,57 +315,31 @@ return: ; This requires phi translation of the adds. define void @test7(i32 %N, ptr nocapture %G) nounwind ssp { -; MDEP-LABEL: @test7( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1 -; MDEP-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8 -; MDEP-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1 -; MDEP-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1 -; MDEP-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64 -; MDEP-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[TMP3:%.*]] = phi double [ 1.000000e+00, [[BB_NPH]] ], [ [[TMP5:%.*]], [[BB]] ] -; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] -; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 -; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]] -; MDEP-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 -; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MDEP-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[TMP5]] = fadd double [[TMP3]], [[TMP4]] -; MDEP-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] -; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test7( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1 -; MSSA-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8 -; MSSA-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1 -; MSSA-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1 -; MSSA-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64 -; MSSA-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] -; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 -; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]] -; MSSA-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 -; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP10]], align 8 -; MSSA-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]] -; MSSA-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] -; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test7( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1 +; CHECK-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1 +; CHECK-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64 +; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[TMP3:%.*]] = phi double [ 1.000000e+00, [[BB_NPH]] ], [ [[TMP5:%.*]], [[BB]] ] +; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] +; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]] +; CHECK-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 +; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] +; CHECK-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[TMP5]] = fadd double [[TMP3]], [[TMP4]] +; CHECK-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: %0 = getelementptr inbounds double, ptr %G, i64 1 @@ -521,37 +375,22 @@ return: ;; Here the loaded address isn't available in 'block2' at all, requiring a new ;; GEP to be inserted into it. define i32 @test8(ptr %p, ptr %q, ptr %Hack, i1 %C) { -; MDEP-LABEL: @test8( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MDEP-NEXT: store i32 0, ptr [[A]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] -; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] -; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MDEP-NEXT: ret i32 [[PRE]] -; -; MSSA-LABEL: @test8( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: br label [[BLOCK4:%.*]] -; MSSA: block3: -; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 -; MSSA-NEXT: store i32 0, ptr [[A]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q:%.*]], [[BLOCK2]] ] -; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4 -; MSSA-NEXT: ret i32 [[PRE]] +; CHECK-LABEL: @test8( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1 +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1 +; CHECK-NEXT: store i32 0, ptr [[A]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ] +; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ] +; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1 +; CHECK-NEXT: ret i32 [[PRE]] ; block1: br i1 %C, label %block2, label %block3 @@ -579,55 +418,31 @@ block4: ; This requires phi translation of the adds. define void @test9(i32 %N, ptr nocapture %G) nounwind ssp { -; MDEP-LABEL: @test9( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 -; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 -; MDEP-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 -; MDEP-NEXT: [[SCEVGEP10_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1 -; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP10_PHI_TRANS_INSERT]], align 8 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] -; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] -; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 -; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]] -; MDEP-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 -; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MDEP-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]] -; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 -; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] -; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test9( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 -; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 -; MSSA-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] -; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 -; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP8]] -; MSSA-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 -; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP10]], align 8 -; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] -; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] -; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test9( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1 +; CHECK-NEXT: [[SCEVGEP10_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1 +; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP10_PHI_TRANS_INSERT]], align 8 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] +; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ] +; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2 +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]] +; CHECK-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1 +; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] +; CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]] +; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: add i32 0, 0 @@ -668,62 +483,35 @@ return: ; PR5501 define void @test10(i32 %N, ptr nocapture %G) nounwind ssp { -; MDEP-LABEL: @test10( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 -; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MDEP: bb.nph: -; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 -; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1 -; MDEP-NEXT: [[SCEVGEP12_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1 -; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP12_PHI_TRANS_INSERT]], align 8 -; MDEP-NEXT: [[DOTPRE1:%.*]] = load double, ptr [[G]], align 8 -; MDEP-NEXT: br label [[BB:%.*]] -; MDEP: bb: -; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE1]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] -; MDEP-NEXT: [[TMP3:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] -; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ] -; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] -; MDEP-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2 -; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MDEP-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1 -; MDEP-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]] -; MDEP-NEXT: [[TMP4]] = load double, ptr [[SCEVGEP10]], align 8 -; MDEP-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]] -; MDEP-NEXT: [[TMP6]] = fadd double [[TMP5]], [[TMP2]] -; MDEP-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8 -; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]] -; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MDEP: return: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test10( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 -; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 -; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] -; MSSA: bb.nph: -; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 -; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1 -; MSSA-NEXT: br label [[BB:%.*]] -; MSSA: bb: -; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ] -; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[INDVAR]] -; MSSA-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2 -; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] -; MSSA-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1 -; MSSA-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]] -; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP12]], align 8 -; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP10]], align 8 -; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]] -; MSSA-NEXT: [[TMP5:%.*]] = load double, ptr [[SCEVGEP]], align 8 -; MSSA-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]] -; MSSA-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8 -; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]] -; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] -; MSSA: return: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test10( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]] +; CHECK: bb.nph: +; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1 +; CHECK-NEXT: [[SCEVGEP12_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1 +; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP12_PHI_TRANS_INSERT]], align 8 +; CHECK-NEXT: [[DOTPRE1:%.*]] = load double, ptr [[G]], align 8 +; CHECK-NEXT: br label [[BB:%.*]] +; CHECK: bb: +; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE1]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ] +; CHECK-NEXT: [[TMP3:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ] +; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ] +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]] +; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2 +; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]] +; CHECK-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1 +; CHECK-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]] +; CHECK-NEXT: [[TMP4]] = load double, ptr [[SCEVGEP10]], align 8 +; CHECK-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]] +; CHECK-NEXT: [[TMP6]] = fadd double [[TMP5]], [[TMP2]] +; CHECK-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]] +; CHECK: return: +; CHECK-NEXT: ret void ; entry: %0 = add i32 %N, -1 @@ -760,40 +548,24 @@ return: ; Test critical edge splitting. define i32 @test11(ptr %p, i1 %C, i32 %N) { -; MDEP-LABEL: @test11( -; MDEP-NEXT: block1: -; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MDEP: block2: -; MDEP-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1 -; MDEP-NEXT: br i1 [[COND]], label [[BLOCK2_BLOCK4_CRIT_EDGE:%.*]], label [[BLOCK5:%.*]] -; MDEP: block2.block4_crit_edge: -; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 -; MDEP-NEXT: br label [[BLOCK4:%.*]] -; MDEP: block3: -; MDEP-NEXT: store i32 0, ptr [[P]], align 4 -; MDEP-NEXT: br label [[BLOCK4]] -; MDEP: block4: -; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ [[PRE_PRE]], [[BLOCK2_BLOCK4_CRIT_EDGE]] ], [ 0, [[BLOCK3]] ] -; MDEP-NEXT: br label [[BLOCK5]] -; MDEP: block5: -; MDEP-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ] -; MDEP-NEXT: ret i32 [[RET]] -; -; MSSA-LABEL: @test11( -; MSSA-NEXT: block1: -; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] -; MSSA: block2: -; MSSA-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1 -; MSSA-NEXT: br i1 [[COND]], label [[BLOCK4:%.*]], label [[BLOCK5:%.*]] -; MSSA: block3: -; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4 -; MSSA-NEXT: br label [[BLOCK4]] -; MSSA: block4: -; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4 -; MSSA-NEXT: br label [[BLOCK5]] -; MSSA: block5: -; MSSA-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ] -; MSSA-NEXT: ret i32 [[RET]] +; CHECK-LABEL: @test11( +; CHECK-NEXT: block1: +; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]] +; CHECK: block2: +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1 +; CHECK-NEXT: br i1 [[COND]], label [[BLOCK2_BLOCK4_CRIT_EDGE:%.*]], label [[BLOCK5:%.*]] +; CHECK: block2.block4_crit_edge: +; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 +; CHECK-NEXT: br label [[BLOCK4:%.*]] +; CHECK: block3: +; CHECK-NEXT: store i32 0, ptr [[P]], align 4 +; CHECK-NEXT: br label [[BLOCK4]] +; CHECK: block4: +; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ [[PRE_PRE]], [[BLOCK2_BLOCK4_CRIT_EDGE]] ], [ 0, [[BLOCK3]] ] +; CHECK-NEXT: br label [[BLOCK5]] +; CHECK: block5: +; CHECK-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ] +; CHECK-NEXT: ret i32 [[RET]] ; block1: br i1 %C, label %block2, label %block3 @@ -955,30 +727,17 @@ follow_2: ; Since it is OK to speculate, PRE is allowed. define i32 @test15(ptr noalias nocapture readonly dereferenceable(8) align 4 %x, ptr noalias nocapture %r, i32 %a) nofree nosync { -; MDEP-LABEL: @test15( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 -; MDEP-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4 -; MDEP-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: call void @f() -; MDEP-NEXT: ret i32 [[VV_PRE]] -; -; MSSA-LABEL: @test15( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 -; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[UU:%.*]] = load i32, ptr [[X:%.*]], align 4 -; MSSA-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: call void @f() -; MSSA-NEXT: [[VV:%.*]] = load i32, ptr [[X]], align 4 -; MSSA-NEXT: ret i32 [[VV]] +; CHECK-LABEL: @test15( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 +; CHECK-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: call void @f() +; CHECK-NEXT: ret i32 [[VV_PRE]] ; entry: @@ -1005,30 +764,17 @@ if.end: ; Since it is OK to speculate, PRE is allowed. define i32 @test16(ptr noalias nocapture readonly dereferenceable(8) align 4 %x, ptr noalias nocapture %r, i32 %a) nofree nosync { -; MDEP-LABEL: @test16( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 -; MDEP-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4 -; MDEP-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: call void @f() -; MDEP-NEXT: ret i32 [[VV_PRE]] -; -; MSSA-LABEL: @test16( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 -; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[UU:%.*]] = load i32, ptr [[X:%.*]], align 4 -; MSSA-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: call void @f() -; MSSA-NEXT: [[VV:%.*]] = load i32, ptr [[X]], align 4 -; MSSA-NEXT: ret i32 [[VV]] +; CHECK-LABEL: @test16( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0 +; CHECK-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: call void @f() +; CHECK-NEXT: ret i32 [[VV_PRE]] ; entry: @@ -1063,67 +809,36 @@ declare i1 @bar() ; We can move all loads into predecessors. define void @test17(ptr %p1, ptr %p2, ptr %p3, ptr %p4) -; MDEP-LABEL: @test17( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 -; MDEP-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200 -; MDEP-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]] -; MDEP: bb1: -; MDEP-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100 -; MDEP-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]] -; MDEP: bb2: -; MDEP-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1 -; MDEP-NEXT: store i64 [[V2]], ptr [[P1]], align 8 -; MDEP-NEXT: br label [[BB3:%.*]] -; MDEP: bb3: -; MDEP-NEXT: [[V3:%.*]] = phi i64 [ [[V3_PRE:%.*]], [[BB200]] ], [ [[V3_PRE1:%.*]], [[BB100]] ], [ [[V2]], [[BB2]] ] -; MDEP-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8 -; MDEP-NEXT: ret void -; MDEP: bb100: -; MDEP-NEXT: [[COND3:%.*]] = call i1 @foo() -; MDEP-NEXT: [[V3_PRE1]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]] -; MDEP: bb101: -; MDEP-NEXT: store i64 [[V3_PRE1]], ptr [[P3:%.*]], align 8 -; MDEP-NEXT: ret void -; MDEP: bb200: -; MDEP-NEXT: [[COND4:%.*]] = call i1 @bar() -; MDEP-NEXT: [[V3_PRE]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]] -; MDEP: bb201: -; MDEP-NEXT: store i64 [[V3_PRE]], ptr [[P4:%.*]], align 8 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test17( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 -; MSSA-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200 -; MSSA-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]] -; MSSA: bb1: -; MSSA-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100 -; MSSA-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]] -; MSSA: bb2: -; MSSA-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1 -; MSSA-NEXT: store i64 [[V2]], ptr [[P1]], align 8 -; MSSA-NEXT: br label [[BB3:%.*]] -; MSSA: bb3: -; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8 -; MSSA-NEXT: ret void -; MSSA: bb100: -; MSSA-NEXT: [[COND3:%.*]] = call i1 @foo() -; MSSA-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]] -; MSSA: bb101: -; MSSA-NEXT: [[V4:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: store i64 [[V4]], ptr [[P3:%.*]], align 8 -; MSSA-NEXT: ret void -; MSSA: bb200: -; MSSA-NEXT: [[COND4:%.*]] = call i1 @bar() -; MSSA-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]] -; MSSA: bb201: -; MSSA-NEXT: [[V5:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: store i64 [[V5]], ptr [[P4:%.*]], align 8 -; MSSA-NEXT: ret void +; CHECK-LABEL: @test17( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 +; CHECK-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200 +; CHECK-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100 +; CHECK-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1 +; CHECK-NEXT: store i64 [[V2]], ptr [[P1]], align 8 +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb3: +; CHECK-NEXT: [[V3:%.*]] = phi i64 [ [[V3_PRE:%.*]], [[BB200]] ], [ [[V3_PRE1:%.*]], [[BB100]] ], [ [[V2]], [[BB2]] ] +; CHECK-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8 +; CHECK-NEXT: ret void +; CHECK: bb100: +; CHECK-NEXT: [[COND3:%.*]] = call i1 @foo() +; CHECK-NEXT: [[V3_PRE1]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]] +; CHECK: bb101: +; CHECK-NEXT: store i64 [[V3_PRE1]], ptr [[P3:%.*]], align 8 +; CHECK-NEXT: ret void +; CHECK: bb200: +; CHECK-NEXT: [[COND4:%.*]] = call i1 @bar() +; CHECK-NEXT: [[V3_PRE]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]] +; CHECK: bb201: +; CHECK-NEXT: store i64 [[V3_PRE]], ptr [[P4:%.*]], align 8 +; CHECK-NEXT: ret void ; { entry: @@ -1168,31 +883,18 @@ bb201: ; So ValuesPerBlock[%if.then] should not be replaced when the load instruction ; is moved to %entry. define void @test18(i1 %cond, ptr %p1, ptr %p2) { -; MDEP-LABEL: @test18( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[V2_PRE:%.*]] = load i16, ptr [[P1:%.*]], align 2 -; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: [[DEC:%.*]] = add i16 [[V2_PRE]], -1 -; MDEP-NEXT: store i16 [[DEC]], ptr [[P1]], align 2 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: [[V2:%.*]] = phi i16 [ [[DEC]], [[IF_THEN]] ], [ [[V2_PRE]], [[ENTRY:%.*]] ] -; MDEP-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test18( -; MSSA-NEXT: entry: -; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[V1:%.*]] = load i16, ptr [[P1:%.*]], align 2 -; MSSA-NEXT: [[DEC:%.*]] = add i16 [[V1]], -1 -; MSSA-NEXT: store i16 [[DEC]], ptr [[P1]], align 2 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: [[V2:%.*]] = load i16, ptr [[P1]], align 2 -; MSSA-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2 -; MSSA-NEXT: ret void +; CHECK-LABEL: @test18( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[V2_PRE:%.*]] = load i16, ptr [[P1:%.*]], align 2 +; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[DEC:%.*]] = add i16 [[V2_PRE]], -1 +; CHECK-NEXT: store i16 [[DEC]], ptr [[P1]], align 2 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[V2:%.*]] = phi i16 [ [[DEC]], [[IF_THEN]] ], [ [[V2_PRE]], [[ENTRY:%.*]] ] +; CHECK-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2 +; CHECK-NEXT: ret void ; entry: br i1 %cond, label %if.end, label %if.then @@ -1211,56 +913,32 @@ if.end: ; PRE of load instructions should not cross exception handling instructions. define void @test19(i1 %cond, ptr %p1, ptr %p2) -; MDEP-LABEL: @test19( -; MDEP-NEXT: entry: -; MDEP-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] -; MDEP: then: -; MDEP-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8 -; MDEP-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1 -; MDEP-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8 -; MDEP-NEXT: br label [[END:%.*]] -; MDEP: else: -; MDEP-NEXT: invoke void @f() -; MDEP-NEXT: to label [[ELSE_END_CRIT_EDGE:%.*]] unwind label [[LPAD:%.*]] -; MDEP: else.end_crit_edge: -; MDEP-NEXT: [[V1_PRE:%.*]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: br label [[END]] -; MDEP: end: -; MDEP-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ELSE_END_CRIT_EDGE]] ], [ [[ADD]], [[THEN]] ] -; MDEP-NEXT: [[AND:%.*]] = and i64 [[V1]], 100 -; MDEP-NEXT: store i64 [[AND]], ptr [[P2]], align 8 -; MDEP-NEXT: ret void -; MDEP: lpad: -; MDEP-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } -; MDEP-NEXT: cleanup -; MDEP-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: [[OR:%.*]] = or i64 [[V3]], 200 -; MDEP-NEXT: store i64 [[OR]], ptr [[P1]], align 8 -; MDEP-NEXT: resume { ptr, i32 } [[LP]] -; -; MSSA-LABEL: @test19( -; MSSA-NEXT: entry: -; MSSA-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] -; MSSA: then: -; MSSA-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8 -; MSSA-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1 -; MSSA-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8 -; MSSA-NEXT: br label [[END:%.*]] -; MSSA: else: -; MSSA-NEXT: invoke void @f() -; MSSA-NEXT: to label [[END]] unwind label [[LPAD:%.*]] -; MSSA: end: -; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: [[AND:%.*]] = and i64 [[V1]], 100 -; MSSA-NEXT: store i64 [[AND]], ptr [[P2]], align 8 -; MSSA-NEXT: ret void -; MSSA: lpad: -; MSSA-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } -; MSSA-NEXT: cleanup -; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: [[OR:%.*]] = or i64 [[V3]], 200 -; MSSA-NEXT: store i64 [[OR]], ptr [[P1]], align 8 -; MSSA-NEXT: resume { ptr, i32 } [[LP]] +; CHECK-LABEL: @test19( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8 +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1 +; CHECK-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8 +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: else: +; CHECK-NEXT: invoke void @f() +; CHECK-NEXT: to label [[ELSE_END_CRIT_EDGE:%.*]] unwind label [[LPAD:%.*]] +; CHECK: else.end_crit_edge: +; CHECK-NEXT: [[V1_PRE:%.*]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ELSE_END_CRIT_EDGE]] ], [ [[ADD]], [[THEN]] ] +; CHECK-NEXT: [[AND:%.*]] = and i64 [[V1]], 100 +; CHECK-NEXT: store i64 [[AND]], ptr [[P2]], align 8 +; CHECK-NEXT: ret void +; CHECK: lpad: +; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } +; CHECK-NEXT: cleanup +; CHECK-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: [[OR:%.*]] = or i64 [[V3]], 200 +; CHECK-NEXT: store i64 [[OR]], ptr [[P1]], align 8 +; CHECK-NEXT: resume { ptr, i32 } [[LP]] ; personality ptr @__CxxFrameHandler3 { entry: @@ -1373,50 +1051,29 @@ if.end: ; Call to function @maybethrow may cause exception, so the load of %v3 can't ; be hoisted to block %if.else. define void @test22(i1 %cond, ptr %p1, ptr %p2) { -; MDEP-LABEL: @test22( -; MDEP-NEXT: entry: -; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; MDEP: if.then: -; MDEP-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 -; MDEP-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1 -; MDEP-NEXT: store i64 [[DEC]], ptr [[P1]], align 8 -; MDEP-NEXT: br label [[IF_END:%.*]] -; MDEP: if.end: -; MDEP-NEXT: [[V2:%.*]] = phi i64 [ [[V2_PRE:%.*]], [[IF_ELSE_IF_END_CRIT_EDGE:%.*]] ], [ [[DEC]], [[IF_THEN]] ] -; MDEP-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8 -; MDEP-NEXT: ret void -; MDEP: if.else: -; MDEP-NEXT: [[COND2:%.*]] = call i1 @foo() -; MDEP-NEXT: br i1 [[COND2]], label [[IF_ELSE_IF_END_CRIT_EDGE]], label [[EXIT:%.*]] -; MDEP: if.else.if.end_crit_edge: -; MDEP-NEXT: [[V2_PRE]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: exit: -; MDEP-NEXT: [[_:%.*]] = call i1 @maybethrow() -; MDEP-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 -; MDEP-NEXT: store i64 [[V3]], ptr [[P2]], align 8 -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test22( -; MSSA-NEXT: entry: -; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 -; MSSA-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1 -; MSSA-NEXT: store i64 [[DEC]], ptr [[P1]], align 8 -; MSSA-NEXT: br label [[IF_END:%.*]] -; MSSA: if.end: -; MSSA-NEXT: [[V2:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8 -; MSSA-NEXT: ret void -; MSSA: if.else: -; MSSA-NEXT: [[COND2:%.*]] = call i1 @foo() -; MSSA-NEXT: br i1 [[COND2]], label [[IF_END]], label [[EXIT:%.*]] -; MSSA: exit: -; MSSA-NEXT: [[_:%.*]] = call i1 @maybethrow() -; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 -; MSSA-NEXT: store i64 [[V3]], ptr [[P2]], align 8 -; MSSA-NEXT: ret void +; CHECK-LABEL: @test22( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8 +; CHECK-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1 +; CHECK-NEXT: store i64 [[DEC]], ptr [[P1]], align 8 +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.end: +; CHECK-NEXT: [[V2:%.*]] = phi i64 [ [[V2_PRE:%.*]], [[IF_ELSE_IF_END_CRIT_EDGE:%.*]] ], [ [[DEC]], [[IF_THEN]] ] +; CHECK-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8 +; CHECK-NEXT: ret void +; CHECK: if.else: +; CHECK-NEXT: [[COND2:%.*]] = call i1 @foo() +; CHECK-NEXT: br i1 [[COND2]], label [[IF_ELSE_IF_END_CRIT_EDGE]], label [[EXIT:%.*]] +; CHECK: if.else.if.end_crit_edge: +; CHECK-NEXT: [[V2_PRE]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: exit: +; CHECK-NEXT: [[_:%.*]] = call i1 @maybethrow() +; CHECK-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8 +; CHECK-NEXT: store i64 [[V3]], ptr [[P2]], align 8 +; CHECK-NEXT: ret void ; entry: br i1 %cond, label %if.then, label %if.else @@ -1450,38 +1107,21 @@ declare void @maybethrow() readnone ; also be replaced by ValuesPerBlock(BB, NewLoad). So we'll not use the deleted ; OldLoad in later PHI instruction. define void @test23(i1 %cond1, i1 %cond2) { -; MDEP-LABEL: @test23( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[G:%.*]] = alloca i64, align 8 -; MDEP-NEXT: [[VAL1_PRE:%.*]] = load i64, ptr @B, align 8 -; MDEP-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]] -; MDEP: then: -; MDEP-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]] -; MDEP: store: -; MDEP-NEXT: store i64 [[VAL1_PRE]], ptr @B, align 8 -; MDEP-NEXT: br label [[WRONG]] -; MDEP: wrong: -; MDEP-NEXT: store i64 [[VAL1_PRE]], ptr [[G]], align 8 -; MDEP-NEXT: ret void -; MDEP: exit: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @test23( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[G:%.*]] = alloca i64, align 8 -; MSSA-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]] -; MSSA: then: -; MSSA-NEXT: [[VAL2:%.*]] = load i64, ptr @B, align 8 -; MSSA-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]] -; MSSA: store: -; MSSA-NEXT: store i64 [[VAL2]], ptr @B, align 8 -; MSSA-NEXT: br label [[WRONG]] -; MSSA: wrong: -; MSSA-NEXT: [[VAL1:%.*]] = load i64, ptr @B, align 8 -; MSSA-NEXT: store i64 [[VAL1]], ptr [[G]], align 8 -; MSSA-NEXT: ret void -; MSSA: exit: -; MSSA-NEXT: ret void +; CHECK-LABEL: @test23( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[G:%.*]] = alloca i64, align 8 +; CHECK-NEXT: [[VAL1_PRE:%.*]] = load i64, ptr @B, align 8 +; CHECK-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]] +; CHECK: then: +; CHECK-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]] +; CHECK: store: +; CHECK-NEXT: store i64 [[VAL1_PRE]], ptr @B, align 8 +; CHECK-NEXT: br label [[WRONG]] +; CHECK: wrong: +; CHECK-NEXT: store i64 [[VAL1_PRE]], ptr [[G]], align 8 +; CHECK-NEXT: ret void +; CHECK: exit: +; CHECK-NEXT: ret void ; entry: %G = alloca i64, align 8 @@ -1509,32 +1149,20 @@ exit: ; dependency with the call. define i32 @test24(ptr noalias %p, ptr noalias %q, i1 %c) { -; MDEP-LABEL: @test24( -; MDEP-NEXT: entry: -; MDEP-NEXT: br i1 [[C:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]], label [[IF_THEN:%.*]] -; MDEP: entry.if.end_crit_edge: -; MDEP-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4 -; MDEP-NEXT: br label [[IF_END:%.*]] -; MDEP: if.then: -; MDEP-NEXT: call void @opaque(ptr [[X]]) -; MDEP-NEXT: [[UU:%.*]] = load i32, ptr [[X]], align 4 -; MDEP-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: [[VV:%.*]] = phi i32 [ [[VV_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[UU]], [[IF_THEN]] ] -; MDEP-NEXT: ret i32 [[VV]] -; -; MSSA-LABEL: @test24( -; MSSA-NEXT: entry: -; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: call void @opaque(ptr [[X:%.*]]) -; MSSA-NEXT: [[UU:%.*]] = load i32, ptr [[X]], align 4 -; MSSA-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: [[VV:%.*]] = load i32, ptr [[X]], align 4 -; MSSA-NEXT: ret i32 [[VV]] +; CHECK-LABEL: @test24( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[C:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]], label [[IF_THEN:%.*]] +; CHECK: entry.if.end_crit_edge: +; CHECK-NEXT: [[L_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4 +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: call void @opaque(ptr [[P]]) +; CHECK-NEXT: [[IDENTICAL_L:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: store i32 [[IDENTICAL_L]], ptr [[Q:%.*]], align 4 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[L:%.*]] = phi i32 [ [[L_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[IDENTICAL_L]], [[IF_THEN]] ] +; CHECK-NEXT: ret i32 [[L]] ; entry: br i1 %c, label %if.end, label %if.then @@ -1551,3 +1179,6 @@ if.end: } declare void @opaque(ptr) nounwind willreturn +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll b/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll index 74bc6bcaecf67..770302fff5325 100644 --- a/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll +++ b/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll @@ -14,56 +14,31 @@ @p = external global i32 define i32 @f(i32 %n) nounwind { -; MDEP-LABEL: define i32 @f( -; MDEP-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { -; MDEP-NEXT: [[ENTRY:.*]]: -; MDEP-NEXT: br label %[[FOR_COND:.*]] -; MDEP: [[FOR_COND]]: -; MDEP-NEXT: [[I_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_INC:.*]] ] -; MDEP-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]] -; MDEP-NEXT: br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_COND_FOR_END_CRIT_EDGE:.*]] -; MDEP: [[FOR_COND_FOR_END_CRIT_EDGE]]: -; MDEP-NEXT: [[TMP9_PRE:%.*]] = load i32, ptr @p, align 4 -; MDEP-NEXT: br label %[[FOR_END:.*]] -; MDEP: [[FOR_BODY]]: -; MDEP-NEXT: [[TMP3:%.*]] = load i32, ptr @p, align 4 -; MDEP-NEXT: [[DEC:%.*]] = add i32 [[TMP3]], -1 -; MDEP-NEXT: store i32 [[DEC]], ptr @p, align 4 -; MDEP-NEXT: [[CMP6:%.*]] = icmp slt i32 [[DEC]], 0 -; MDEP-NEXT: br i1 [[CMP6]], label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_INC]] -; MDEP: [[FOR_BODY_FOR_END_CRIT_EDGE]]: -; MDEP-NEXT: br label %[[FOR_END]] -; MDEP: [[FOR_INC]]: -; MDEP-NEXT: [[INDVAR_NEXT]] = add i32 [[I_0]], 1 -; MDEP-NEXT: br label %[[FOR_COND]] -; MDEP: [[FOR_END]]: -; MDEP-NEXT: [[TMP9:%.*]] = phi i32 [ [[DEC]], %[[FOR_BODY_FOR_END_CRIT_EDGE]] ], [ [[TMP9_PRE]], %[[FOR_COND_FOR_END_CRIT_EDGE]] ] -; MDEP-NEXT: ret i32 [[TMP9]] -; -; MSSA-LABEL: define i32 @f( -; MSSA-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { -; MSSA-NEXT: [[ENTRY:.*]]: -; MSSA-NEXT: br label %[[FOR_COND:.*]] -; MSSA: [[FOR_COND]]: -; MSSA-NEXT: [[I_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_INC:.*]] ] -; MSSA-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]] -; MSSA-NEXT: br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_COND_FOR_END_CRIT_EDGE:.*]] -; MSSA: [[FOR_COND_FOR_END_CRIT_EDGE]]: -; MSSA-NEXT: br label %[[FOR_END:.*]] -; MSSA: [[FOR_BODY]]: -; MSSA-NEXT: [[TMP3:%.*]] = load i32, ptr @p, align 4 -; MSSA-NEXT: [[DEC:%.*]] = add i32 [[TMP3]], -1 -; MSSA-NEXT: store i32 [[DEC]], ptr @p, align 4 -; MSSA-NEXT: [[CMP6:%.*]] = icmp slt i32 [[DEC]], 0 -; MSSA-NEXT: br i1 [[CMP6]], label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_INC]] -; MSSA: [[FOR_BODY_FOR_END_CRIT_EDGE]]: -; MSSA-NEXT: br label %[[FOR_END]] -; MSSA: [[FOR_INC]]: -; MSSA-NEXT: [[INDVAR_NEXT]] = add i32 [[I_0]], 1 -; MSSA-NEXT: br label %[[FOR_COND]] -; MSSA: [[FOR_END]]: -; MSSA-NEXT: [[TMP9:%.*]] = load i32, ptr @p, align 4 -; MSSA-NEXT: ret i32 [[TMP9]] +; CHECK-LABEL: define i32 @f( +; CHECK-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[FOR_COND:.*]] +; CHECK: [[FOR_COND]]: +; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_INC:.*]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]] +; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_COND_FOR_END_CRIT_EDGE:.*]] +; CHECK: [[FOR_COND_FOR_END_CRIT_EDGE]]: +; CHECK-NEXT: [[TMP9_PRE:%.*]] = load i32, ptr @p, align 4 +; CHECK-NEXT: br label %[[FOR_END:.*]] +; CHECK: [[FOR_BODY]]: +; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @p, align 4 +; CHECK-NEXT: [[DEC:%.*]] = add i32 [[TMP3]], -1 +; CHECK-NEXT: store i32 [[DEC]], ptr @p, align 4 +; CHECK-NEXT: [[CMP6:%.*]] = icmp slt i32 [[DEC]], 0 +; CHECK-NEXT: br i1 [[CMP6]], label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_INC]] +; CHECK: [[FOR_BODY_FOR_END_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[FOR_END]] +; CHECK: [[FOR_INC]]: +; CHECK-NEXT: [[INDVAR_NEXT]] = add i32 [[I_0]], 1 +; CHECK-NEXT: br label %[[FOR_COND]] +; CHECK: [[FOR_END]]: +; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[DEC]], %[[FOR_BODY_FOR_END_CRIT_EDGE]] ], [ [[TMP9_PRE]], %[[FOR_COND_FOR_END_CRIT_EDGE]] ] +; CHECK-NEXT: ret i32 [[TMP9]] ; entry: br label %for.cond @@ -95,4 +70,5 @@ for.end: ; preds = %for.body.for.end_crit_edge, %for.cond.for.end_crit_edge ret i32 %tmp9 } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll index 49ee089fed393..578d057d0e02a 100644 --- a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll +++ b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll @@ -7,38 +7,22 @@ target datalayout = "e-p:64:64:64" ; GVN should preserve the TBAA tag on loads when doing PRE. define void @test(ptr %P, ptr %Q, i1 %arg) nounwind { -; MDEP-LABEL: define void @test( -; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { -; MDEP-NEXT: [[ENTRY:.*:]] -; MDEP-NEXT: br i1 [[ARG]], label %[[BB_NPH:.*]], label %[[FOR_END:.*]] -; MDEP: [[BB_NPH]]: -; MDEP-NEXT: [[TMP33_PRE:%.*]] = load i16, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0:![0-9]+]] -; MDEP-NEXT: br label %[[FOR_BODY:.*]] -; MDEP: [[FOR_BODY]]: -; MDEP-NEXT: [[TMP33:%.*]] = phi i16 [ 0, %[[FOR_BODY]] ], [ [[TMP33_PRE]], %[[BB_NPH]] ] -; MDEP-NEXT: store i16 [[TMP33]], ptr [[Q]], align 2 -; MDEP-NEXT: store i16 0, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0]] -; MDEP-NEXT: br i1 false, label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_BODY]] -; MDEP: [[FOR_BODY_FOR_END_CRIT_EDGE]]: -; MDEP-NEXT: br label %[[FOR_END]] -; MDEP: [[FOR_END]]: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: define void @test( -; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { -; MSSA-NEXT: [[ENTRY:.*:]] -; MSSA-NEXT: br i1 [[ARG]], label %[[BB_NPH:.*]], label %[[FOR_END:.*]] -; MSSA: [[BB_NPH]]: -; MSSA-NEXT: br label %[[FOR_BODY:.*]] -; MSSA: [[FOR_BODY]]: -; MSSA-NEXT: [[TMP33:%.*]] = load i16, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0:![0-9]+]] -; MSSA-NEXT: store i16 [[TMP33]], ptr [[Q]], align 2 -; MSSA-NEXT: store i16 0, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0]] -; MSSA-NEXT: br i1 false, label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_BODY]] -; MSSA: [[FOR_BODY_FOR_END_CRIT_EDGE]]: -; MSSA-NEXT: br label %[[FOR_END]] -; MSSA: [[FOR_END]]: -; MSSA-NEXT: ret void +; CHECK-LABEL: define void @test( +; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: br i1 [[ARG]], label %[[BB_NPH:.*]], label %[[FOR_END:.*]] +; CHECK: [[BB_NPH]]: +; CHECK-NEXT: [[TMP33_PRE:%.*]] = load i16, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0:![0-9]+]] +; CHECK-NEXT: br label %[[FOR_BODY:.*]] +; CHECK: [[FOR_BODY]]: +; CHECK-NEXT: [[TMP33:%.*]] = phi i16 [ 0, %[[FOR_BODY]] ], [ [[TMP33_PRE]], %[[BB_NPH]] ] +; CHECK-NEXT: store i16 [[TMP33]], ptr [[Q]], align 2 +; CHECK-NEXT: store i16 0, ptr [[P]], align 2, !tbaa [[SHORT_TBAA0]] +; CHECK-NEXT: br i1 false, label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_BODY]] +; CHECK: [[FOR_BODY_FOR_END_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[FOR_END]] +; CHECK: [[FOR_END]]: +; CHECK-NEXT: ret void ; entry: br i1 %arg, label %bb.nph, label %for.end @@ -62,15 +46,11 @@ for.end: ; preds = %for.body, %entry !2 = !{!"Simple C/C++ TBAA"} !3 = !{!"short", !1} ;. -; MDEP: [[SHORT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} -; MDEP: [[META1]] = !{!"short", [[META2:![0-9]+]]} -; MDEP: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]} -; MDEP: [[META3]] = !{!"Simple C/C++ TBAA"} -;. -; MSSA: [[SHORT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} -; MSSA: [[META1]] = !{!"short", [[META2:![0-9]+]]} -; MSSA: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]} -; MSSA: [[META3]] = !{!"Simple C/C++ TBAA"} +; CHECK: [[SHORT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0} +; CHECK: [[META1]] = !{!"short", [[META2:![0-9]+]]} +; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]} +; CHECK: [[META3]] = !{!"Simple C/C++ TBAA"} ;. ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/rle-addrspace-cast.ll b/llvm/test/Transforms/GVN/PRE/rle-addrspace-cast.ll index 6c79b02efbd24..9231ba4bea0f4 100644 --- a/llvm/test/Transforms/GVN/PRE/rle-addrspace-cast.ll +++ b/llvm/test/Transforms/GVN/PRE/rle-addrspace-cast.ll @@ -3,20 +3,12 @@ ; RUN: opt < %s -data-layout="e-p:32:32:32-p1:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -passes='gvn',dce -S | FileCheck %s --check-prefixes=CHECK,MSSA define i8 @coerce_offset0_addrspacecast(i32 %V, ptr %P) { -; MDEP-LABEL: define i8 @coerce_offset0_addrspacecast( -; MDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; MDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; MDEP-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 16 -; MDEP-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 -; MDEP-NEXT: ret i8 [[TMP2]] -; -; MSSA-LABEL: define i8 @coerce_offset0_addrspacecast( -; MSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; MSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; MSSA-NEXT: [[P2:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1) -; MSSA-NEXT: [[P3:%.*]] = getelementptr i8, ptr addrspace(1) [[P2]], i32 2 -; MSSA-NEXT: [[A:%.*]] = load i8, ptr addrspace(1) [[P3]], align 1 -; MSSA-NEXT: ret i8 [[A]] +; CHECK-LABEL: define i8 @coerce_offset0_addrspacecast( +; CHECK-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 16 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 +; CHECK-NEXT: ret i8 [[TMP2]] ; store i32 %V, ptr %P @@ -27,4 +19,5 @@ define i8 @coerce_offset0_addrspacecast(i32 %V, ptr %P) { ret i8 %A } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/rle-semidominated.ll b/llvm/test/Transforms/GVN/PRE/rle-semidominated.ll index 4eb090e18110e..16ecc637b13ad 100644 --- a/llvm/test/Transforms/GVN/PRE/rle-semidominated.ll +++ b/llvm/test/Transforms/GVN/PRE/rle-semidominated.ll @@ -3,35 +3,20 @@ ; RUN: opt < %s -passes='gvn' -S | FileCheck %s --check-prefixes=CHECK,MSSA define i32 @main(ptr %p, i32 %x, i32 %y) { -; MDEP-LABEL: define i32 @main( -; MDEP-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MDEP-NEXT: [[BLOCK1:.*:]] -; MDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; MDEP-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MDEP: [[BLOCK2]]: -; MDEP-NEXT: [[DEAD_PRE:%.*]] = load i32, ptr [[P]], align 4 -; MDEP-NEXT: br label %[[BLOCK4:.*]] -; MDEP: [[BLOCK3]]: -; MDEP-NEXT: store i32 0, ptr [[P]], align 4 -; MDEP-NEXT: br label %[[BLOCK4]] -; MDEP: [[BLOCK4]]: -; MDEP-NEXT: [[DEAD:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[DEAD_PRE]], %[[BLOCK2]] ] -; MDEP-NEXT: ret i32 [[DEAD]] -; -; MSSA-LABEL: define i32 @main( -; MSSA-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; MSSA-NEXT: [[BLOCK1:.*:]] -; MSSA-NEXT: [[Z:%.*]] = load i32, ptr [[P]], align 4 -; MSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; MSSA-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; MSSA: [[BLOCK2]]: -; MSSA-NEXT: br label %[[BLOCK4:.*]] -; MSSA: [[BLOCK3]]: -; MSSA-NEXT: store i32 0, ptr [[P]], align 4 -; MSSA-NEXT: br label %[[BLOCK4]] -; MSSA: [[BLOCK4]]: -; MSSA-NEXT: [[DEAD:%.*]] = load i32, ptr [[P]], align 4 -; MSSA-NEXT: ret i32 [[DEAD]] +; CHECK-LABEL: define i32 @main( +; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[BLOCK1:.*:]] +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] +; CHECK-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] +; CHECK: [[BLOCK2]]: +; CHECK-NEXT: [[DEAD_PRE:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[BLOCK4:.*]] +; CHECK: [[BLOCK3]]: +; CHECK-NEXT: store i32 0, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[BLOCK4]] +; CHECK: [[BLOCK4]]: +; CHECK-NEXT: [[DEAD:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[DEAD_PRE]], %[[BLOCK2]] ] +; CHECK-NEXT: ret i32 [[DEAD]] ; block1: %z = load i32, ptr %p @@ -52,4 +37,5 @@ block4: } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/PRE/rle.ll b/llvm/test/Transforms/GVN/PRE/rle.ll index e495163fa43cd..49fe873c0141f 100644 --- a/llvm/test/Transforms/GVN/PRE/rle.ll +++ b/llvm/test/Transforms/GVN/PRE/rle.ll @@ -6,27 +6,10 @@ ;; Trivial RLE test. define i32 @test0(i32 %V, ptr %P) { -; LE-MEMDEP-LABEL: define i32 @test0( -; LE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: ret i32 [[V]] -; -; LE-MEMSSA-LABEL: define i32 @test0( -; LE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret i32 [[A]] -; -; BE-MEMDEP-LABEL: define i32 @test0( -; BE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: ret i32 [[V]] -; -; BE-MEMSSA-LABEL: define i32 @test0( -; BE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret i32 [[A]] +; CHECK-LABEL: define i32 @test0( +; CHECK-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 +; CHECK-NEXT: ret i32 [[V]] ; store i32 %V, ptr %P @@ -73,29 +56,11 @@ define void @crash1() { ;; i32 -> f32 forwarding. define float @coerce_mustalias1(i32 %V, ptr %P) { -; LE-MEMDEP-LABEL: define float @coerce_mustalias1( -; LE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast i32 [[V]] to float -; LE-MEMDEP-NEXT: ret float [[TMP1]] -; -; LE-MEMSSA-LABEL: define float @coerce_mustalias1( -; LE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret float [[A]] -; -; BE-MEMDEP-LABEL: define float @coerce_mustalias1( -; BE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast i32 [[V]] to float -; BE-MEMDEP-NEXT: ret float [[TMP1]] -; -; BE-MEMSSA-LABEL: define float @coerce_mustalias1( -; BE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret float [[A]] +; CHECK-LABEL: define float @coerce_mustalias1( +; CHECK-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[V]] to float +; CHECK-NEXT: ret float [[TMP1]] ; store i32 %V, ptr %P @@ -106,31 +71,12 @@ define float @coerce_mustalias1(i32 %V, ptr %P) { ;; ptr -> float forwarding. define float @coerce_mustalias2(ptr %V, ptr %P) { -; LE-MEMDEP-LABEL: define float @coerce_mustalias2( -; LE-MEMDEP-SAME: ptr [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store ptr [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[V]] to i32 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float -; LE-MEMDEP-NEXT: ret float [[TMP2]] -; -; LE-MEMSSA-LABEL: define float @coerce_mustalias2( -; LE-MEMSSA-SAME: ptr [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store ptr [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret float [[A]] -; -; BE-MEMDEP-LABEL: define float @coerce_mustalias2( -; BE-MEMDEP-SAME: ptr [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store ptr [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[V]] to i32 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float -; BE-MEMDEP-NEXT: ret float [[TMP2]] -; -; BE-MEMSSA-LABEL: define float @coerce_mustalias2( -; BE-MEMSSA-SAME: ptr [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store ptr [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret float [[A]] +; CHECK-LABEL: define float @coerce_mustalias2( +; CHECK-SAME: ptr [[V:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: store ptr [[V]], ptr [[P]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[V]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float +; CHECK-NEXT: ret float [[TMP2]] ; store ptr %V, ptr %P @@ -141,31 +87,12 @@ define float @coerce_mustalias2(ptr %V, ptr %P) { ;; float -> ptr forwarding. define ptr @coerce_mustalias3(float %V, ptr %P) { -; LE-MEMDEP-LABEL: define ptr @coerce_mustalias3( -; LE-MEMDEP-SAME: float [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store float [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast float [[V]] to i32 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to ptr -; LE-MEMDEP-NEXT: ret ptr [[TMP2]] -; -; LE-MEMSSA-LABEL: define ptr @coerce_mustalias3( -; LE-MEMSSA-SAME: float [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store float [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret ptr [[A]] -; -; BE-MEMDEP-LABEL: define ptr @coerce_mustalias3( -; BE-MEMDEP-SAME: float [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store float [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast float [[V]] to i32 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to ptr -; BE-MEMDEP-NEXT: ret ptr [[TMP2]] -; -; BE-MEMSSA-LABEL: define ptr @coerce_mustalias3( -; BE-MEMSSA-SAME: float [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store float [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret ptr [[A]] +; CHECK-LABEL: define ptr @coerce_mustalias3( +; CHECK-SAME: float [[V:%.*]], ptr [[P:%.*]]) { +; CHECK-NEXT: store float [[V]], ptr [[P]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[V]] to i32 +; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to ptr +; CHECK-NEXT: ret ptr [[TMP2]] ; store float %V, ptr %P @@ -176,47 +103,15 @@ define ptr @coerce_mustalias3(float %V, ptr %P) { ;; i32 -> f32 load forwarding. define float @coerce_mustalias4(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define float @coerce_mustalias4( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast i32 [[A]] to float -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: ret float [[TMP1]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: ret float [[TMP1]] -; -; LE-MEMSSA-LABEL: define float @coerce_mustalias4( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[B:%.*]] = load float, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: ret float [[B]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: [[X:%.*]] = bitcast i32 [[A]] to float -; LE-MEMSSA-NEXT: ret float [[X]] -; -; BE-MEMDEP-LABEL: define float @coerce_mustalias4( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = bitcast i32 [[A]] to float -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: ret float [[TMP1]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: ret float [[TMP1]] -; -; BE-MEMSSA-LABEL: define float @coerce_mustalias4( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[B:%.*]] = load float, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: ret float [[B]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: [[X:%.*]] = bitcast i32 [[A]] to float -; BE-MEMSSA-NEXT: ret float [[X]] +; CHECK-LABEL: define float @coerce_mustalias4( +; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[A]] to float +; CHECK-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; CHECK: [[T]]: +; CHECK-NEXT: ret float [[TMP1]] +; CHECK: [[F]]: +; CHECK-NEXT: ret float [[TMP1]] ; %A = load i32, ptr %P @@ -233,30 +128,18 @@ F: ;; i32 -> i8 forwarding define i8 @coerce_mustalias5(i32 %V, ptr %P) { -; LE-MEMDEP-LABEL: define i8 @coerce_mustalias5( -; LE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[V]] to i8 -; LE-MEMDEP-NEXT: ret i8 [[TMP1]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_mustalias5( -; LE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_mustalias5( -; BE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 24 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 -; BE-MEMDEP-NEXT: ret i8 [[TMP2]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_mustalias5( -; BE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_mustalias5( +; LE-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; LE-NEXT: store i32 [[V]], ptr [[P]], align 4 +; LE-NEXT: [[TMP1:%.*]] = trunc i32 [[V]] to i8 +; LE-NEXT: ret i8 [[TMP1]] +; +; BE-LABEL: define i8 @coerce_mustalias5( +; BE-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; BE-NEXT: store i32 [[V]], ptr [[P]], align 4 +; BE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 24 +; BE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 +; BE-NEXT: ret i8 [[TMP2]] ; store i32 %V, ptr %P @@ -267,32 +150,20 @@ define i8 @coerce_mustalias5(i32 %V, ptr %P) { ;; i64 -> float forwarding define float @coerce_mustalias6(i64 %V, ptr %P) { -; LE-MEMDEP-LABEL: define float @coerce_mustalias6( -; LE-MEMDEP-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i64 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float -; LE-MEMDEP-NEXT: ret float [[TMP2]] -; -; LE-MEMSSA-LABEL: define float @coerce_mustalias6( -; LE-MEMSSA-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i64 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret float [[A]] -; -; BE-MEMDEP-LABEL: define float @coerce_mustalias6( -; BE-MEMDEP-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i64 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; BE-MEMDEP-NEXT: [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float -; BE-MEMDEP-NEXT: ret float [[TMP3]] -; -; BE-MEMSSA-LABEL: define float @coerce_mustalias6( -; BE-MEMSSA-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i64 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load float, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret float [[A]] +; LE-LABEL: define float @coerce_mustalias6( +; LE-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { +; LE-NEXT: store i64 [[V]], ptr [[P]], align 4 +; LE-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32 +; LE-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float +; LE-NEXT: ret float [[TMP2]] +; +; BE-LABEL: define float @coerce_mustalias6( +; BE-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { +; BE-NEXT: store i64 [[V]], ptr [[P]], align 4 +; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32 +; BE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; BE-NEXT: [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float +; BE-NEXT: ret float [[TMP3]] ; store i64 %V, ptr %P @@ -303,32 +174,20 @@ define float @coerce_mustalias6(i64 %V, ptr %P) { ;; i64 -> ptr (32-bit) forwarding define ptr @coerce_mustalias7(i64 %V, ptr %P) { -; LE-MEMDEP-LABEL: define ptr @coerce_mustalias7( -; LE-MEMDEP-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i64 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to ptr -; LE-MEMDEP-NEXT: ret ptr [[TMP2]] -; -; LE-MEMSSA-LABEL: define ptr @coerce_mustalias7( -; LE-MEMSSA-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i64 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: ret ptr [[A]] -; -; BE-MEMDEP-LABEL: define ptr @coerce_mustalias7( -; BE-MEMDEP-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i64 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 -; BE-MEMDEP-NEXT: [[TMP3:%.*]] = inttoptr i32 [[TMP2]] to ptr -; BE-MEMDEP-NEXT: ret ptr [[TMP3]] -; -; BE-MEMSSA-LABEL: define ptr @coerce_mustalias7( -; BE-MEMSSA-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i64 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load ptr, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: ret ptr [[A]] +; LE-LABEL: define ptr @coerce_mustalias7( +; LE-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { +; LE-NEXT: store i64 [[V]], ptr [[P]], align 4 +; LE-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32 +; LE-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to ptr +; LE-NEXT: ret ptr [[TMP2]] +; +; BE-LABEL: define ptr @coerce_mustalias7( +; BE-SAME: i64 [[V:%.*]], ptr [[P:%.*]]) { +; BE-NEXT: store i64 [[V]], ptr [[P]], align 4 +; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32 +; BE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 +; BE-NEXT: [[TMP3:%.*]] = inttoptr i32 [[TMP2]] to ptr +; BE-NEXT: ret ptr [[TMP3]] ; store i64 %V, ptr %P @@ -339,33 +198,11 @@ define ptr @coerce_mustalias7(i64 %V, ptr %P) { ; memset -> i16 forwarding. define signext i16 @memset_to_i16_local(ptr %A) nounwind ssp { -; LE-MEMDEP-LABEL: define signext i16 @memset_to_i16_local( -; LE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 1, i64 200, i1 false) -; LE-MEMDEP-NEXT: ret i16 257 -; -; LE-MEMSSA-LABEL: define signext i16 @memset_to_i16_local( -; LE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 1, i64 200, i1 false) -; LE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 42 -; LE-MEMSSA-NEXT: [[TTMP2:%.*]] = load i16, ptr [[ARRAYIDX]], align 2 -; LE-MEMSSA-NEXT: ret i16 [[TTMP2]] -; -; BE-MEMDEP-LABEL: define signext i16 @memset_to_i16_local( -; BE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 1, i64 200, i1 false) -; BE-MEMDEP-NEXT: ret i16 257 -; -; BE-MEMSSA-LABEL: define signext i16 @memset_to_i16_local( -; BE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 1, i64 200, i1 false) -; BE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 42 -; BE-MEMSSA-NEXT: [[TTMP2:%.*]] = load i16, ptr [[ARRAYIDX]], align 2 -; BE-MEMSSA-NEXT: ret i16 [[TTMP2]] +; CHECK-LABEL: define signext i16 @memset_to_i16_local( +; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 1, i64 200, i1 false) +; CHECK-NEXT: ret i16 257 ; entry: tail call void @llvm.memset.p0.i64(ptr %A, i8 1, i64 200, i1 false) @@ -376,45 +213,17 @@ entry: ; memset -> float forwarding. define float @memset_to_float_local(ptr %A, i8 %Val) nounwind ssp { -; LE-MEMDEP-LABEL: define float @memset_to_float_local( -; LE-MEMDEP-SAME: ptr [[A:%.*]], i8 [[VAL:%.*]]) #[[ATTR0]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 [[VAL]], i64 400, i1 false) -; LE-MEMDEP-NEXT: [[TMP0:%.*]] = zext i8 [[VAL]] to i32 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = shl i32 [[TMP0]], 8 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = or i32 [[TMP0]], [[TMP1]] -; LE-MEMDEP-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 16 -; LE-MEMDEP-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]] -; LE-MEMDEP-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float -; LE-MEMDEP-NEXT: ret float [[TMP5]] -; -; LE-MEMSSA-LABEL: define float @memset_to_float_local( -; LE-MEMSSA-SAME: ptr [[A:%.*]], i8 [[VAL:%.*]]) #[[ATTR0]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 [[VAL]], i64 400, i1 false) -; LE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 42 -; LE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; LE-MEMSSA-NEXT: ret float [[TTMP2]] -; -; BE-MEMDEP-LABEL: define float @memset_to_float_local( -; BE-MEMDEP-SAME: ptr [[A:%.*]], i8 [[VAL:%.*]]) #[[ATTR0]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 [[VAL]], i64 400, i1 false) -; BE-MEMDEP-NEXT: [[TMP0:%.*]] = zext i8 [[VAL]] to i32 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = shl i32 [[TMP0]], 8 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = or i32 [[TMP0]], [[TMP1]] -; BE-MEMDEP-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 16 -; BE-MEMDEP-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]] -; BE-MEMDEP-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float -; BE-MEMDEP-NEXT: ret float [[TMP5]] -; -; BE-MEMSSA-LABEL: define float @memset_to_float_local( -; BE-MEMSSA-SAME: ptr [[A:%.*]], i8 [[VAL:%.*]]) #[[ATTR0]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 [[VAL]], i64 400, i1 false) -; BE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 42 -; BE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; BE-MEMSSA-NEXT: ret float [[TTMP2]] +; CHECK-LABEL: define float @memset_to_float_local( +; CHECK-SAME: ptr [[A:%.*]], i8 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[A]], i8 [[VAL]], i64 400, i1 false) +; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[VAL]] to i32 +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[TMP0]], 8 +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP0]], [[TMP1]] +; CHECK-NEXT: [[TMP3:%.*]] = shl i32 [[TMP2]], 16 +; CHECK-NEXT: [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float +; CHECK-NEXT: ret float [[TMP5]] ; entry: tail call void @llvm.memset.p0.i64(ptr %A, i8 %Val, i64 400, i1 false) @@ -425,59 +234,18 @@ entry: ;; non-local memset -> i16 load forwarding. define i16 @memset_to_i16_nonlocal0(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i16 @memset_to_i16_nonlocal0( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 1, i64 400, i1 false) -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 400, i1 false) -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i16 [ 514, %[[F]] ], [ 257, %[[T]] ] -; LE-MEMDEP-NEXT: ret i16 [[A]] -; -; LE-MEMSSA-LABEL: define i16 @memset_to_i16_nonlocal0( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 1, i64 400, i1 false) -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 400, i1 false) -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[P2:%.*]] = getelementptr i16, ptr [[P]], i32 4 -; LE-MEMSSA-NEXT: [[A:%.*]] = load i16, ptr [[P2]], align 2 -; LE-MEMSSA-NEXT: ret i16 [[A]] -; -; BE-MEMDEP-LABEL: define i16 @memset_to_i16_nonlocal0( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 1, i64 400, i1 false) -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 400, i1 false) -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i16 [ 514, %[[F]] ], [ 257, %[[T]] ] -; BE-MEMDEP-NEXT: ret i16 [[A]] -; -; BE-MEMSSA-LABEL: define i16 @memset_to_i16_nonlocal0( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 1, i64 400, i1 false) -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 400, i1 false) -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[P2:%.*]] = getelementptr i16, ptr [[P]], i32 4 -; BE-MEMSSA-NEXT: [[A:%.*]] = load i16, ptr [[P2]], align 2 -; BE-MEMSSA-NEXT: ret i16 [[A]] +; CHECK-LABEL: define i16 @memset_to_i16_nonlocal0( +; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; CHECK: [[T]]: +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 1, i64 400, i1 false) +; CHECK-NEXT: br label %[[CONT:.*]] +; CHECK: [[F]]: +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 400, i1 false) +; CHECK-NEXT: br label %[[CONT]] +; CHECK: [[CONT]]: +; CHECK-NEXT: [[A:%.*]] = phi i16 [ 514, %[[F]] ], [ 257, %[[T]] ] +; CHECK-NEXT: ret i16 [[A]] ; br i1 %cond, label %T, label %F T: @@ -500,33 +268,11 @@ Cont: ; memset -> float forwarding. define float @memcpy_to_float_local(ptr %A) nounwind ssp { -; LE-MEMDEP-LABEL: define float @memcpy_to_float_local( -; LE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr @GCst, i64 12, i1 false) -; LE-MEMDEP-NEXT: ret float 1.400000e+01 -; -; LE-MEMSSA-LABEL: define float @memcpy_to_float_local( -; LE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr @GCst, i64 12, i1 false) -; LE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 1 -; LE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; LE-MEMSSA-NEXT: ret float [[TTMP2]] -; -; BE-MEMDEP-LABEL: define float @memcpy_to_float_local( -; BE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr @GCst, i64 12, i1 false) -; BE-MEMDEP-NEXT: ret float 1.400000e+01 -; -; BE-MEMSSA-LABEL: define float @memcpy_to_float_local( -; BE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr @GCst, i64 12, i1 false) -; BE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 1 -; BE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; BE-MEMSSA-NEXT: ret float [[TTMP2]] +; CHECK-LABEL: define float @memcpy_to_float_local( +; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr @GCst, i64 12, i1 false) +; CHECK-NEXT: ret float 1.400000e+01 ; entry: tail call void @llvm.memcpy.p0.p0.i64(ptr %A, ptr @GCst, i64 12, i1 false) @@ -537,33 +283,11 @@ entry: ; memcpy from address space 1 define float @memcpy_to_float_local_as1(ptr %A) nounwind ssp { -; LE-MEMDEP-LABEL: define float @memcpy_to_float_local_as1( -; LE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: tail call void @llvm.memcpy.p0.p1.i64(ptr [[A]], ptr addrspace(1) @GCst_as1, i64 12, i1 false) -; LE-MEMDEP-NEXT: ret float 1.400000e+01 -; -; LE-MEMSSA-LABEL: define float @memcpy_to_float_local_as1( -; LE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: tail call void @llvm.memcpy.p0.p1.i64(ptr [[A]], ptr addrspace(1) @GCst_as1, i64 12, i1 false) -; LE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 1 -; LE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; LE-MEMSSA-NEXT: ret float [[TTMP2]] -; -; BE-MEMDEP-LABEL: define float @memcpy_to_float_local_as1( -; BE-MEMDEP-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: tail call void @llvm.memcpy.p0.p1.i64(ptr [[A]], ptr addrspace(1) @GCst_as1, i64 12, i1 false) -; BE-MEMDEP-NEXT: ret float 1.400000e+01 -; -; BE-MEMSSA-LABEL: define float @memcpy_to_float_local_as1( -; BE-MEMSSA-SAME: ptr [[A:%.*]]) #[[ATTR0]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: tail call void @llvm.memcpy.p0.p1.i64(ptr [[A]], ptr addrspace(1) @GCst_as1, i64 12, i1 false) -; BE-MEMSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 1 -; BE-MEMSSA-NEXT: [[TTMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4 -; BE-MEMSSA-NEXT: ret float [[TTMP2]] +; CHECK-LABEL: define float @memcpy_to_float_local_as1( +; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p1.i64(ptr [[A]], ptr addrspace(1) @GCst_as1, i64 12, i1 false) +; CHECK-NEXT: ret float 1.400000e+01 ; entry: tail call void @llvm.memcpy.p0.p1.i64(ptr %A, ptr addrspace(1) @GCst_as1, i64 12, i1 false) @@ -574,57 +298,31 @@ entry: ;; non-local i32/float -> i8 load forwarding. define i8 @coerce_mustalias_nonlocal0(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i8 @coerce_mustalias_nonlocal0( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ 42, %[[T]] ] -; LE-MEMDEP-NEXT: ret i8 [[A]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_mustalias_nonlocal0( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_mustalias_nonlocal0( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ 63, %[[F]] ], [ 0, %[[T]] ] -; BE-MEMDEP-NEXT: ret i8 [[A]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_mustalias_nonlocal0( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_mustalias_nonlocal0( +; LE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; LE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; LE: [[T]]: +; LE-NEXT: store i32 42, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT:.*]] +; LE: [[F]]: +; LE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT]] +; LE: [[CONT]]: +; LE-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ 42, %[[T]] ] +; LE-NEXT: ret i8 [[A]] +; +; BE-LABEL: define i8 @coerce_mustalias_nonlocal0( +; BE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; BE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; BE: [[T]]: +; BE-NEXT: store i32 42, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT:.*]] +; BE: [[F]]: +; BE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT]] +; BE: [[CONT]]: +; BE-NEXT: [[A:%.*]] = phi i8 [ 63, %[[F]] ], [ 0, %[[T]] ] +; BE-NEXT: ret i8 [[A]] ; br i1 %cond, label %T, label %F T: @@ -645,57 +343,31 @@ Cont: ;; non-local i32/float -> i8 load forwarding. This also tests that the "P3" ;; bitcast equivalence can be properly phi translated. define i8 @coerce_mustalias_nonlocal1(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i8 @coerce_mustalias_nonlocal1( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ 42, %[[T]] ] -; LE-MEMDEP-NEXT: ret i8 [[A]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_mustalias_nonlocal1( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_mustalias_nonlocal1( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ 63, %[[F]] ], [ 0, %[[T]] ] -; BE-MEMDEP-NEXT: ret i8 [[A]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_mustalias_nonlocal1( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_mustalias_nonlocal1( +; LE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; LE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; LE: [[T]]: +; LE-NEXT: store i32 42, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT:.*]] +; LE: [[F]]: +; LE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT]] +; LE: [[CONT]]: +; LE-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ 42, %[[T]] ] +; LE-NEXT: ret i8 [[A]] +; +; BE-LABEL: define i8 @coerce_mustalias_nonlocal1( +; BE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; BE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; BE: [[T]]: +; BE-NEXT: store i32 42, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT:.*]] +; BE: [[F]]: +; BE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT]] +; BE: [[CONT]]: +; BE-NEXT: [[A:%.*]] = phi i8 [ 63, %[[F]] ], [ 0, %[[T]] ] +; BE-NEXT: ret i8 [[A]] ; br i1 %cond, label %T, label %F T: @@ -715,55 +387,31 @@ Cont: ;; non-local i32 -> i8 partial redundancy load forwarding. define i8 @coerce_mustalias_pre0(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i8 @coerce_mustalias_pre0( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P]], align 1 -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 42, %[[T]] ] -; LE-MEMDEP-NEXT: ret i8 [[A]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_mustalias_pre0( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_mustalias_pre0( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P]], align 1 -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 0, %[[T]] ] -; BE-MEMDEP-NEXT: ret i8 [[A]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_mustalias_pre0( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_mustalias_pre0( +; LE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; LE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; LE: [[T]]: +; LE-NEXT: store i32 42, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT:.*]] +; LE: [[F]]: +; LE-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P]], align 1 +; LE-NEXT: br label %[[CONT]] +; LE: [[CONT]]: +; LE-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 42, %[[T]] ] +; LE-NEXT: ret i8 [[A]] +; +; BE-LABEL: define i8 @coerce_mustalias_pre0( +; BE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; BE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; BE: [[T]]: +; BE-NEXT: store i32 42, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT:.*]] +; BE: [[F]]: +; BE-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P]], align 1 +; BE-NEXT: br label %[[CONT]] +; BE: [[CONT]]: +; BE-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 0, %[[T]] ] +; BE-NEXT: ret i8 [[A]] ; br i1 %cond, label %T, label %F T: @@ -787,33 +435,19 @@ Cont: ;; i32 -> i8 forwarding. ;; PR4216 define i8 @coerce_offset0(i32 %V, ptr %P) { -; LE-MEMDEP-LABEL: define i8 @coerce_offset0( -; LE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 16 -; LE-MEMDEP-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 -; LE-MEMDEP-NEXT: ret i8 [[TMP2]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_offset0( -; LE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P3]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_offset0( -; BE-MEMDEP-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 8 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 -; BE-MEMDEP-NEXT: ret i8 [[TMP2]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_offset0( -; BE-MEMSSA-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: store i32 [[V]], ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P3]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_offset0( +; LE-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; LE-NEXT: store i32 [[V]], ptr [[P]], align 4 +; LE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 16 +; LE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 +; LE-NEXT: ret i8 [[TMP2]] +; +; BE-LABEL: define i8 @coerce_offset0( +; BE-SAME: i32 [[V:%.*]], ptr [[P:%.*]]) { +; BE-NEXT: store i32 [[V]], ptr [[P]], align 4 +; BE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 8 +; BE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 +; BE-NEXT: ret i8 [[TMP2]] ; store i32 %V, ptr %P @@ -825,59 +459,31 @@ define i8 @coerce_offset0(i32 %V, ptr %P) { ;; non-local i32/float -> i8 load forwarding. define i8 @coerce_offset_nonlocal0(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i8 @coerce_offset_nonlocal0( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: store i32 57005, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ -128, %[[F]] ], [ 0, %[[T]] ] -; LE-MEMDEP-NEXT: ret i8 [[A]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_offset_nonlocal0( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: store i32 57005, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P4]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_offset_nonlocal0( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: store i32 57005, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ -34, %[[T]] ] -; BE-MEMDEP-NEXT: ret i8 [[A]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_offset_nonlocal0( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: store i32 57005, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: store float 1.000000e+00, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P4]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; LE-LABEL: define i8 @coerce_offset_nonlocal0( +; LE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; LE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; LE: [[T]]: +; LE-NEXT: store i32 57005, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT:.*]] +; LE: [[F]]: +; LE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; LE-NEXT: br label %[[CONT]] +; LE: [[CONT]]: +; LE-NEXT: [[A:%.*]] = phi i8 [ -128, %[[F]] ], [ 0, %[[T]] ] +; LE-NEXT: ret i8 [[A]] +; +; BE-LABEL: define i8 @coerce_offset_nonlocal0( +; BE-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; BE-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; BE: [[T]]: +; BE-NEXT: store i32 57005, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT:.*]] +; BE: [[F]]: +; BE-NEXT: store float 1.000000e+00, ptr [[P]], align 4 +; BE-NEXT: br label %[[CONT]] +; BE: [[CONT]]: +; BE-NEXT: [[A:%.*]] = phi i8 [ 0, %[[F]] ], [ -34, %[[T]] ] +; BE-NEXT: ret i8 [[A]] ; %P4 = getelementptr i8, ptr %P, i32 2 br i1 %cond, label %T, label %F @@ -898,59 +504,19 @@ Cont: ;; non-local i32 -> i8 partial redundancy load forwarding. define i8 @coerce_offset_pre0(ptr %P, i1 %cond) { -; LE-MEMDEP-LABEL: define i8 @coerce_offset_pre0( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMDEP: [[T]]: -; LE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[CONT:.*]] -; LE-MEMDEP: [[F]]: -; LE-MEMDEP-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P4]], align 1 -; LE-MEMDEP-NEXT: br label %[[CONT]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 0, %[[T]] ] -; LE-MEMDEP-NEXT: ret i8 [[A]] -; -; LE-MEMSSA-LABEL: define i8 @coerce_offset_pre0( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; LE-MEMSSA: [[T]]: -; LE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[CONT:.*]] -; LE-MEMSSA: [[F]]: -; LE-MEMSSA-NEXT: br label %[[CONT]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P4]], align 1 -; LE-MEMSSA-NEXT: ret i8 [[A]] -; -; BE-MEMDEP-LABEL: define i8 @coerce_offset_pre0( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMDEP: [[T]]: -; BE-MEMDEP-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[CONT:.*]] -; BE-MEMDEP: [[F]]: -; BE-MEMDEP-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P4]], align 1 -; BE-MEMDEP-NEXT: br label %[[CONT]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 0, %[[T]] ] -; BE-MEMDEP-NEXT: ret i8 [[A]] -; -; BE-MEMSSA-LABEL: define i8 @coerce_offset_pre0( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] -; BE-MEMSSA: [[T]]: -; BE-MEMSSA-NEXT: store i32 42, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[CONT:.*]] -; BE-MEMSSA: [[F]]: -; BE-MEMSSA-NEXT: br label %[[CONT]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = load i8, ptr [[P4]], align 1 -; BE-MEMSSA-NEXT: ret i8 [[A]] +; CHECK-LABEL: define i8 @coerce_offset_pre0( +; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P]], i32 2 +; CHECK-NEXT: br i1 [[COND]], label %[[T:.*]], label %[[F:.*]] +; CHECK: [[T]]: +; CHECK-NEXT: store i32 42, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[CONT:.*]] +; CHECK: [[F]]: +; CHECK-NEXT: [[A_PRE:%.*]] = load i8, ptr [[P4]], align 1 +; CHECK-NEXT: br label %[[CONT]] +; CHECK: [[CONT]]: +; CHECK-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], %[[F]] ], [ 0, %[[T]] ] +; CHECK-NEXT: ret i8 [[A]] ; %P4 = getelementptr i8, ptr %P, i32 2 br i1 %cond, label %T, label %F @@ -968,71 +534,21 @@ Cont: } define i32 @chained_load(ptr %p, i32 %x, i32 %y) { -; LE-MEMDEP-LABEL: define i32 @chained_load( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; LE-MEMDEP-NEXT: [[BLOCK1:.*:]] -; LE-MEMDEP-NEXT: [[A:%.*]] = alloca ptr, align 4 -; LE-MEMDEP-NEXT: [[Z:%.*]] = load ptr, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: store ptr [[Z]], ptr [[A]], align 4 -; LE-MEMDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; LE-MEMDEP-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; LE-MEMDEP: [[BLOCK2]]: -; LE-MEMDEP-NEXT: br label %[[BLOCK4:.*]] -; LE-MEMDEP: [[BLOCK3]]: -; LE-MEMDEP-NEXT: br label %[[BLOCK4]] -; LE-MEMDEP: [[BLOCK4]]: -; LE-MEMDEP-NEXT: [[D:%.*]] = load i32, ptr [[Z]], align 4 -; LE-MEMDEP-NEXT: ret i32 [[D]] -; -; LE-MEMSSA-LABEL: define i32 @chained_load( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; LE-MEMSSA-NEXT: [[BLOCK1:.*:]] -; LE-MEMSSA-NEXT: [[A:%.*]] = alloca ptr, align 4 -; LE-MEMSSA-NEXT: [[Z:%.*]] = load ptr, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: store ptr [[Z]], ptr [[A]], align 4 -; LE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; LE-MEMSSA-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; LE-MEMSSA: [[BLOCK2]]: -; LE-MEMSSA-NEXT: br label %[[BLOCK4:.*]] -; LE-MEMSSA: [[BLOCK3]]: -; LE-MEMSSA-NEXT: br label %[[BLOCK4]] -; LE-MEMSSA: [[BLOCK4]]: -; LE-MEMSSA-NEXT: [[C:%.*]] = load ptr, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[D:%.*]] = load i32, ptr [[C]], align 4 -; LE-MEMSSA-NEXT: ret i32 [[D]] -; -; BE-MEMDEP-LABEL: define i32 @chained_load( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; BE-MEMDEP-NEXT: [[BLOCK1:.*:]] -; BE-MEMDEP-NEXT: [[A:%.*]] = alloca ptr, align 4 -; BE-MEMDEP-NEXT: [[Z:%.*]] = load ptr, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: store ptr [[Z]], ptr [[A]], align 4 -; BE-MEMDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; BE-MEMDEP-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; BE-MEMDEP: [[BLOCK2]]: -; BE-MEMDEP-NEXT: br label %[[BLOCK4:.*]] -; BE-MEMDEP: [[BLOCK3]]: -; BE-MEMDEP-NEXT: br label %[[BLOCK4]] -; BE-MEMDEP: [[BLOCK4]]: -; BE-MEMDEP-NEXT: [[D:%.*]] = load i32, ptr [[Z]], align 4 -; BE-MEMDEP-NEXT: ret i32 [[D]] -; -; BE-MEMSSA-LABEL: define i32 @chained_load( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { -; BE-MEMSSA-NEXT: [[BLOCK1:.*:]] -; BE-MEMSSA-NEXT: [[A:%.*]] = alloca ptr, align 4 -; BE-MEMSSA-NEXT: [[Z:%.*]] = load ptr, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: store ptr [[Z]], ptr [[A]], align 4 -; BE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] -; BE-MEMSSA-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; BE-MEMSSA: [[BLOCK2]]: -; BE-MEMSSA-NEXT: br label %[[BLOCK4:.*]] -; BE-MEMSSA: [[BLOCK3]]: -; BE-MEMSSA-NEXT: br label %[[BLOCK4]] -; BE-MEMSSA: [[BLOCK4]]: -; BE-MEMSSA-NEXT: [[C:%.*]] = load ptr, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[D:%.*]] = load i32, ptr [[C]], align 4 -; BE-MEMSSA-NEXT: ret i32 [[D]] +; CHECK-LABEL: define i32 @chained_load( +; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[BLOCK1:.*:]] +; CHECK-NEXT: [[A:%.*]] = alloca ptr, align 4 +; CHECK-NEXT: [[Z:%.*]] = load ptr, ptr [[P]], align 4 +; CHECK-NEXT: store ptr [[Z]], ptr [[A]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]] +; CHECK-NEXT: br i1 [[CMP]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] +; CHECK: [[BLOCK2]]: +; CHECK-NEXT: br label %[[BLOCK4:.*]] +; CHECK: [[BLOCK3]]: +; CHECK-NEXT: br label %[[BLOCK4]] +; CHECK: [[BLOCK4]]: +; CHECK-NEXT: [[D:%.*]] = load i32, ptr [[Z]], align 4 +; CHECK-NEXT: ret i32 [[D]] ; block1: %A = alloca ptr @@ -1120,123 +636,33 @@ TY: } define i32 @phi_trans3(ptr %p, i32 %x, i32 %y, i32 %z) { -; LE-MEMDEP-LABEL: define i32 @phi_trans3( -; LE-MEMDEP-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; LE-MEMDEP-NEXT: [[BLOCK1:.*:]] -; LE-MEMDEP-NEXT: [[CMPXY:%.*]] = icmp eq i32 [[X]], [[Y]] -; LE-MEMDEP-NEXT: br i1 [[CMPXY]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; LE-MEMDEP: [[BLOCK2]]: -; LE-MEMDEP-NEXT: store i32 87, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: br label %[[BLOCK4:.*]] -; LE-MEMDEP: [[BLOCK3]]: -; LE-MEMDEP-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 43 -; LE-MEMDEP-NEXT: store i32 97, ptr [[P2]], align 4 -; LE-MEMDEP-NEXT: br label %[[BLOCK4]] -; LE-MEMDEP: [[BLOCK4]]: -; LE-MEMDEP-NEXT: [[D:%.*]] = phi i32 [ 87, %[[BLOCK2]] ], [ 97, %[[BLOCK3]] ] -; LE-MEMDEP-NEXT: br i1 [[CMPXY]], label %[[BLOCK5:.*]], label %[[EXIT:.*]] -; LE-MEMDEP: [[BLOCK5]]: -; LE-MEMDEP-NEXT: br i1 true, label %[[BLOCK6:.*]], label %[[BLOCK5_EXIT_CRIT_EDGE:.*]] -; LE-MEMDEP: [[BLOCK5_EXIT_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: br label %[[EXIT]] -; LE-MEMDEP: [[BLOCK6]]: -; LE-MEMDEP-NEXT: br i1 true, label %[[BLOCK7:.*]], label %[[BLOCK6_EXIT_CRIT_EDGE:.*]] -; LE-MEMDEP: [[BLOCK6_EXIT_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: br label %[[EXIT]] -; LE-MEMDEP: [[BLOCK7]]: -; LE-MEMDEP-NEXT: ret i32 [[D]] -; LE-MEMDEP: [[EXIT]]: -; LE-MEMDEP-NEXT: ret i32 -1 -; -; LE-MEMSSA-LABEL: define i32 @phi_trans3( -; LE-MEMSSA-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; LE-MEMSSA-NEXT: [[BLOCK1:.*:]] -; LE-MEMSSA-NEXT: [[CMPXY:%.*]] = icmp eq i32 [[X]], [[Y]] -; LE-MEMSSA-NEXT: br i1 [[CMPXY]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; LE-MEMSSA: [[BLOCK2]]: -; LE-MEMSSA-NEXT: store i32 87, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: br label %[[BLOCK4:.*]] -; LE-MEMSSA: [[BLOCK3]]: -; LE-MEMSSA-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 43 -; LE-MEMSSA-NEXT: store i32 97, ptr [[P2]], align 4 -; LE-MEMSSA-NEXT: br label %[[BLOCK4]] -; LE-MEMSSA: [[BLOCK4]]: -; LE-MEMSSA-NEXT: [[A:%.*]] = phi i32 [ -1, %[[BLOCK2]] ], [ 42, %[[BLOCK3]] ] -; LE-MEMSSA-NEXT: br i1 [[CMPXY]], label %[[BLOCK5:.*]], label %[[EXIT:.*]] -; LE-MEMSSA: [[BLOCK5]]: -; LE-MEMSSA-NEXT: [[B:%.*]] = add i32 [[A]], 1 -; LE-MEMSSA-NEXT: br i1 true, label %[[BLOCK6:.*]], label %[[BLOCK5_EXIT_CRIT_EDGE:.*]] -; LE-MEMSSA: [[BLOCK5_EXIT_CRIT_EDGE]]: -; LE-MEMSSA-NEXT: br label %[[EXIT]] -; LE-MEMSSA: [[BLOCK6]]: -; LE-MEMSSA-NEXT: [[C:%.*]] = getelementptr i32, ptr [[P]], i32 [[B]] -; LE-MEMSSA-NEXT: br i1 true, label %[[BLOCK7:.*]], label %[[BLOCK6_EXIT_CRIT_EDGE:.*]] -; LE-MEMSSA: [[BLOCK6_EXIT_CRIT_EDGE]]: -; LE-MEMSSA-NEXT: br label %[[EXIT]] -; LE-MEMSSA: [[BLOCK7]]: -; LE-MEMSSA-NEXT: [[D:%.*]] = load i32, ptr [[C]], align 4 -; LE-MEMSSA-NEXT: ret i32 [[D]] -; LE-MEMSSA: [[EXIT]]: -; LE-MEMSSA-NEXT: ret i32 -1 -; -; BE-MEMDEP-LABEL: define i32 @phi_trans3( -; BE-MEMDEP-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; BE-MEMDEP-NEXT: [[BLOCK1:.*:]] -; BE-MEMDEP-NEXT: [[CMPXY:%.*]] = icmp eq i32 [[X]], [[Y]] -; BE-MEMDEP-NEXT: br i1 [[CMPXY]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; BE-MEMDEP: [[BLOCK2]]: -; BE-MEMDEP-NEXT: store i32 87, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: br label %[[BLOCK4:.*]] -; BE-MEMDEP: [[BLOCK3]]: -; BE-MEMDEP-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 43 -; BE-MEMDEP-NEXT: store i32 97, ptr [[P2]], align 4 -; BE-MEMDEP-NEXT: br label %[[BLOCK4]] -; BE-MEMDEP: [[BLOCK4]]: -; BE-MEMDEP-NEXT: [[D:%.*]] = phi i32 [ 87, %[[BLOCK2]] ], [ 97, %[[BLOCK3]] ] -; BE-MEMDEP-NEXT: br i1 [[CMPXY]], label %[[BLOCK5:.*]], label %[[EXIT:.*]] -; BE-MEMDEP: [[BLOCK5]]: -; BE-MEMDEP-NEXT: br i1 true, label %[[BLOCK6:.*]], label %[[BLOCK5_EXIT_CRIT_EDGE:.*]] -; BE-MEMDEP: [[BLOCK5_EXIT_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: br label %[[EXIT]] -; BE-MEMDEP: [[BLOCK6]]: -; BE-MEMDEP-NEXT: br i1 true, label %[[BLOCK7:.*]], label %[[BLOCK6_EXIT_CRIT_EDGE:.*]] -; BE-MEMDEP: [[BLOCK6_EXIT_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: br label %[[EXIT]] -; BE-MEMDEP: [[BLOCK7]]: -; BE-MEMDEP-NEXT: ret i32 [[D]] -; BE-MEMDEP: [[EXIT]]: -; BE-MEMDEP-NEXT: ret i32 -1 -; -; BE-MEMSSA-LABEL: define i32 @phi_trans3( -; BE-MEMSSA-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { -; BE-MEMSSA-NEXT: [[BLOCK1:.*:]] -; BE-MEMSSA-NEXT: [[CMPXY:%.*]] = icmp eq i32 [[X]], [[Y]] -; BE-MEMSSA-NEXT: br i1 [[CMPXY]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] -; BE-MEMSSA: [[BLOCK2]]: -; BE-MEMSSA-NEXT: store i32 87, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: br label %[[BLOCK4:.*]] -; BE-MEMSSA: [[BLOCK3]]: -; BE-MEMSSA-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 43 -; BE-MEMSSA-NEXT: store i32 97, ptr [[P2]], align 4 -; BE-MEMSSA-NEXT: br label %[[BLOCK4]] -; BE-MEMSSA: [[BLOCK4]]: -; BE-MEMSSA-NEXT: [[A:%.*]] = phi i32 [ -1, %[[BLOCK2]] ], [ 42, %[[BLOCK3]] ] -; BE-MEMSSA-NEXT: br i1 [[CMPXY]], label %[[BLOCK5:.*]], label %[[EXIT:.*]] -; BE-MEMSSA: [[BLOCK5]]: -; BE-MEMSSA-NEXT: [[B:%.*]] = add i32 [[A]], 1 -; BE-MEMSSA-NEXT: br i1 true, label %[[BLOCK6:.*]], label %[[BLOCK5_EXIT_CRIT_EDGE:.*]] -; BE-MEMSSA: [[BLOCK5_EXIT_CRIT_EDGE]]: -; BE-MEMSSA-NEXT: br label %[[EXIT]] -; BE-MEMSSA: [[BLOCK6]]: -; BE-MEMSSA-NEXT: [[C:%.*]] = getelementptr i32, ptr [[P]], i32 [[B]] -; BE-MEMSSA-NEXT: br i1 true, label %[[BLOCK7:.*]], label %[[BLOCK6_EXIT_CRIT_EDGE:.*]] -; BE-MEMSSA: [[BLOCK6_EXIT_CRIT_EDGE]]: -; BE-MEMSSA-NEXT: br label %[[EXIT]] -; BE-MEMSSA: [[BLOCK7]]: -; BE-MEMSSA-NEXT: [[D:%.*]] = load i32, ptr [[C]], align 4 -; BE-MEMSSA-NEXT: ret i32 [[D]] -; BE-MEMSSA: [[EXIT]]: -; BE-MEMSSA-NEXT: ret i32 -1 +; CHECK-LABEL: define i32 @phi_trans3( +; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) { +; CHECK-NEXT: [[BLOCK1:.*:]] +; CHECK-NEXT: [[CMPXY:%.*]] = icmp eq i32 [[X]], [[Y]] +; CHECK-NEXT: br i1 [[CMPXY]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]] +; CHECK: [[BLOCK2]]: +; CHECK-NEXT: store i32 87, ptr [[P]], align 4 +; CHECK-NEXT: br label %[[BLOCK4:.*]] +; CHECK: [[BLOCK3]]: +; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P]], i32 43 +; CHECK-NEXT: store i32 97, ptr [[P2]], align 4 +; CHECK-NEXT: br label %[[BLOCK4]] +; CHECK: [[BLOCK4]]: +; CHECK-NEXT: [[D:%.*]] = phi i32 [ 87, %[[BLOCK2]] ], [ 97, %[[BLOCK3]] ] +; CHECK-NEXT: br i1 [[CMPXY]], label %[[BLOCK5:.*]], label %[[EXIT:.*]] +; CHECK: [[BLOCK5]]: +; CHECK-NEXT: br i1 true, label %[[BLOCK6:.*]], label %[[BLOCK5_EXIT_CRIT_EDGE:.*]] +; CHECK: [[BLOCK5_EXIT_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[EXIT]] +; CHECK: [[BLOCK6]]: +; CHECK-NEXT: br i1 true, label %[[BLOCK7:.*]], label %[[BLOCK6_EXIT_CRIT_EDGE:.*]] +; CHECK: [[BLOCK6_EXIT_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[EXIT]] +; CHECK: [[BLOCK7]]: +; CHECK-NEXT: ret i32 [[D]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret i32 -1 ; block1: %cmpxy = icmp eq i32 %x, %y @@ -1274,77 +700,22 @@ exit: } define i8 @phi_trans4(ptr %p) { -; LE-MEMDEP-LABEL: define i8 @phi_trans4( -; LE-MEMDEP-SAME: ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[X3:%.*]] = getelementptr i8, ptr [[P]], i32 192 -; LE-MEMDEP-NEXT: store i8 -64, ptr [[X3]], align 1 -; LE-MEMDEP-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; LE-MEMDEP-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; LE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; LE-MEMDEP: [[LOOP]]: -; LE-MEMDEP-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ 0, %[[LOOP]] ] -; LE-MEMDEP-NEXT: [[COND:%.*]] = call i1 @cond2() -; LE-MEMDEP-NEXT: store i32 0, ptr [[X3]], align 4 -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[OUT:.*]] -; LE-MEMDEP: [[OUT]]: -; LE-MEMDEP-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; LE-MEMDEP-NEXT: ret i8 [[R]] -; -; LE-MEMSSA-LABEL: define i8 @phi_trans4( -; LE-MEMSSA-SAME: ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[X3:%.*]] = getelementptr i8, ptr [[P]], i32 192 -; LE-MEMSSA-NEXT: store i8 -64, ptr [[X3]], align 1 -; LE-MEMSSA-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; LE-MEMSSA-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; LE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; LE-MEMSSA: [[LOOP]]: -; LE-MEMSSA-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 192, %[[LOOP]] ] -; LE-MEMSSA-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; LE-MEMSSA-NEXT: [[Y2:%.*]] = load i8, ptr [[X2]], align 1 -; LE-MEMSSA-NEXT: [[COND:%.*]] = call i1 @cond2() -; LE-MEMSSA-NEXT: store i32 0, ptr [[X3]], align 4 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[OUT:.*]] -; LE-MEMSSA: [[OUT]]: -; LE-MEMSSA-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; LE-MEMSSA-NEXT: ret i8 [[R]] -; -; BE-MEMDEP-LABEL: define i8 @phi_trans4( -; BE-MEMDEP-SAME: ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[X3:%.*]] = getelementptr i8, ptr [[P]], i32 192 -; BE-MEMDEP-NEXT: store i8 -64, ptr [[X3]], align 1 -; BE-MEMDEP-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; BE-MEMDEP-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; BE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; BE-MEMDEP: [[LOOP]]: -; BE-MEMDEP-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ 0, %[[LOOP]] ] -; BE-MEMDEP-NEXT: [[COND:%.*]] = call i1 @cond2() -; BE-MEMDEP-NEXT: store i32 0, ptr [[X3]], align 4 -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[OUT:.*]] -; BE-MEMDEP: [[OUT]]: -; BE-MEMDEP-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; BE-MEMDEP-NEXT: ret i8 [[R]] -; -; BE-MEMSSA-LABEL: define i8 @phi_trans4( -; BE-MEMSSA-SAME: ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[X3:%.*]] = getelementptr i8, ptr [[P]], i32 192 -; BE-MEMSSA-NEXT: store i8 -64, ptr [[X3]], align 1 -; BE-MEMSSA-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; BE-MEMSSA-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; BE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; BE-MEMSSA: [[LOOP]]: -; BE-MEMSSA-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 192, %[[LOOP]] ] -; BE-MEMSSA-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; BE-MEMSSA-NEXT: [[Y2:%.*]] = load i8, ptr [[X2]], align 1 -; BE-MEMSSA-NEXT: [[COND:%.*]] = call i1 @cond2() -; BE-MEMSSA-NEXT: store i32 0, ptr [[X3]], align 4 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[OUT:.*]] -; BE-MEMSSA: [[OUT]]: -; BE-MEMSSA-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; BE-MEMSSA-NEXT: ret i8 [[R]] +; CHECK-LABEL: define i8 @phi_trans4( +; CHECK-SAME: ptr [[P:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[X3:%.*]] = getelementptr i8, ptr [[P]], i32 192 +; CHECK-NEXT: store i8 -64, ptr [[X3]], align 1 +; CHECK-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 +; CHECK-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ 0, %[[LOOP]] ] +; CHECK-NEXT: [[COND:%.*]] = call i1 @cond2() +; CHECK-NEXT: store i32 0, ptr [[X3]], align 4 +; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[OUT:.*]] +; CHECK: [[OUT]]: +; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] +; CHECK-NEXT: ret i8 [[R]] ; entry: %X3 = getelementptr i8, ptr %p, i32 192 @@ -1371,97 +742,29 @@ out: } define i8 @phi_trans5(ptr %p) { -; LE-MEMDEP-LABEL: define i8 @phi_trans5( -; LE-MEMDEP-SAME: ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[X4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMDEP-NEXT: store i8 19, ptr [[X4]], align 1 -; LE-MEMDEP-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; LE-MEMDEP-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; LE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; LE-MEMDEP: [[LOOP]]: -; LE-MEMDEP-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ [[Y2_PRE:%.*]], %[[CONT:.*]] ] -; LE-MEMDEP-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 3, %[[CONT]] ] -; LE-MEMDEP-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; LE-MEMDEP-NEXT: [[COND:%.*]] = call i1 @cond2() -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[CONT]], label %[[OUT:.*]] -; LE-MEMDEP: [[CONT]]: -; LE-MEMDEP-NEXT: [[Z:%.*]] = getelementptr i8, ptr [[X2]], i32 -1 -; LE-MEMDEP-NEXT: store i32 50462976, ptr [[Z]], align 4 -; LE-MEMDEP-NEXT: [[X2_PHI_TRANS_INSERT:%.*]] = getelementptr i8, ptr [[P]], i32 3 -; LE-MEMDEP-NEXT: [[Y2_PRE]] = load i8, ptr [[X2_PHI_TRANS_INSERT]], align 1 -; LE-MEMDEP-NEXT: br label %[[LOOP]] -; LE-MEMDEP: [[OUT]]: -; LE-MEMDEP-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; LE-MEMDEP-NEXT: ret i8 [[R]] -; -; LE-MEMSSA-LABEL: define i8 @phi_trans5( -; LE-MEMSSA-SAME: ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[X4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; LE-MEMSSA-NEXT: store i8 19, ptr [[X4]], align 1 -; LE-MEMSSA-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; LE-MEMSSA-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; LE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; LE-MEMSSA: [[LOOP]]: -; LE-MEMSSA-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 3, %[[CONT:.*]] ] -; LE-MEMSSA-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; LE-MEMSSA-NEXT: [[Y2:%.*]] = load i8, ptr [[X2]], align 1 -; LE-MEMSSA-NEXT: [[COND:%.*]] = call i1 @cond2() -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[CONT]], label %[[OUT:.*]] -; LE-MEMSSA: [[CONT]]: -; LE-MEMSSA-NEXT: [[Z:%.*]] = getelementptr i8, ptr [[X2]], i32 -1 -; LE-MEMSSA-NEXT: store i32 50462976, ptr [[Z]], align 4 -; LE-MEMSSA-NEXT: br label %[[LOOP]] -; LE-MEMSSA: [[OUT]]: -; LE-MEMSSA-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; LE-MEMSSA-NEXT: ret i8 [[R]] -; -; BE-MEMDEP-LABEL: define i8 @phi_trans5( -; BE-MEMDEP-SAME: ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[X4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMDEP-NEXT: store i8 19, ptr [[X4]], align 1 -; BE-MEMDEP-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; BE-MEMDEP-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; BE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; BE-MEMDEP: [[LOOP]]: -; BE-MEMDEP-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ [[Y2_PRE:%.*]], %[[CONT:.*]] ] -; BE-MEMDEP-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 3, %[[CONT]] ] -; BE-MEMDEP-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; BE-MEMDEP-NEXT: [[COND:%.*]] = call i1 @cond2() -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[CONT]], label %[[OUT:.*]] -; BE-MEMDEP: [[CONT]]: -; BE-MEMDEP-NEXT: [[Z:%.*]] = getelementptr i8, ptr [[X2]], i32 -1 -; BE-MEMDEP-NEXT: store i32 50462976, ptr [[Z]], align 4 -; BE-MEMDEP-NEXT: [[X2_PHI_TRANS_INSERT:%.*]] = getelementptr i8, ptr [[P]], i32 3 -; BE-MEMDEP-NEXT: [[Y2_PRE]] = load i8, ptr [[X2_PHI_TRANS_INSERT]], align 1 -; BE-MEMDEP-NEXT: br label %[[LOOP]] -; BE-MEMDEP: [[OUT]]: -; BE-MEMDEP-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; BE-MEMDEP-NEXT: ret i8 [[R]] -; -; BE-MEMSSA-LABEL: define i8 @phi_trans5( -; BE-MEMSSA-SAME: ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[X4:%.*]] = getelementptr i8, ptr [[P]], i32 2 -; BE-MEMSSA-NEXT: store i8 19, ptr [[X4]], align 1 -; BE-MEMSSA-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 -; BE-MEMSSA-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 -; BE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; BE-MEMSSA: [[LOOP]]: -; BE-MEMSSA-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 3, %[[CONT:.*]] ] -; BE-MEMSSA-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] -; BE-MEMSSA-NEXT: [[Y2:%.*]] = load i8, ptr [[X2]], align 1 -; BE-MEMSSA-NEXT: [[COND:%.*]] = call i1 @cond2() -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[CONT]], label %[[OUT:.*]] -; BE-MEMSSA: [[CONT]]: -; BE-MEMSSA-NEXT: [[Z:%.*]] = getelementptr i8, ptr [[X2]], i32 -1 -; BE-MEMSSA-NEXT: store i32 50462976, ptr [[Z]], align 4 -; BE-MEMSSA-NEXT: br label %[[LOOP]] -; BE-MEMSSA: [[OUT]]: -; BE-MEMSSA-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] -; BE-MEMSSA-NEXT: ret i8 [[R]] +; CHECK-LABEL: define i8 @phi_trans5( +; CHECK-SAME: ptr [[P:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[X4:%.*]] = getelementptr i8, ptr [[P]], i32 2 +; CHECK-NEXT: store i8 19, ptr [[X4]], align 1 +; CHECK-NEXT: [[X:%.*]] = getelementptr i8, ptr [[P]], i32 4 +; CHECK-NEXT: [[Y:%.*]] = load i8, ptr [[X]], align 1 +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[Y2:%.*]] = phi i8 [ [[Y]], %[[ENTRY]] ], [ [[Y2_PRE:%.*]], %[[CONT:.*]] ] +; CHECK-NEXT: [[I:%.*]] = phi i32 [ 4, %[[ENTRY]] ], [ 3, %[[CONT]] ] +; CHECK-NEXT: [[X2:%.*]] = getelementptr i8, ptr [[P]], i32 [[I]] +; CHECK-NEXT: [[COND:%.*]] = call i1 @cond2() +; CHECK-NEXT: br i1 [[COND]], label %[[CONT]], label %[[OUT:.*]] +; CHECK: [[CONT]]: +; CHECK-NEXT: [[Z:%.*]] = getelementptr i8, ptr [[X2]], i32 -1 +; CHECK-NEXT: store i32 50462976, ptr [[Z]], align 4 +; CHECK-NEXT: [[X2_PHI_TRANS_INSERT:%.*]] = getelementptr i8, ptr [[P]], i32 3 +; CHECK-NEXT: [[Y2_PRE]] = load i8, ptr [[X2_PHI_TRANS_INSERT]], align 1 +; CHECK-NEXT: br label %[[LOOP]] +; CHECK: [[OUT]]: +; CHECK-NEXT: [[R:%.*]] = add i8 [[Y]], [[Y2]] +; CHECK-NEXT: ret i8 [[R]] ; entry: @@ -1497,79 +800,25 @@ declare void @use_i32(i32) readonly ; into header. Make sure we translate the address for %l1 correctly where ; parts of the address computations are in different basic blocks. define i32 @phi_trans6(ptr noalias nocapture readonly %x, i1 %cond) { -; LE-MEMDEP-LABEL: define i32 @phi_trans6( -; LE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; LE-MEMDEP: [[HEADER]]: -; LE-MEMDEP-NEXT: [[L1:%.*]] = phi i32 [ [[L0]], %[[ENTRY]] ], [ [[L1_PRE:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; LE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE]] ] -; LE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans6, %[[LATCH:.*]]), [label %latch] -; LE-MEMDEP: [[LATCH]]: -; LE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; LE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[X]], i32 [[IV_NEXT]] -; LE-MEMDEP-NEXT: [[L1_PRE]] = load i32, ptr [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT]], align 4 -; LE-MEMDEP-NEXT: br label %[[HEADER]] -; LE-MEMDEP: [[EXIT]]: -; LE-MEMDEP-NEXT: ret i32 [[L1]] -; -; LE-MEMSSA-LABEL: define i32 @phi_trans6( -; LE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; LE-MEMSSA: [[HEADER]]: -; LE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; LE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans6, %[[LATCH]]), [label %latch] -; LE-MEMSSA: [[LATCH]]: -; LE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[IV]] -; LE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; LE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; LE-MEMSSA: [[EXIT]]: -; LE-MEMSSA-NEXT: ret i32 [[L1]] -; -; BE-MEMDEP-LABEL: define i32 @phi_trans6( -; BE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; BE-MEMDEP: [[HEADER]]: -; BE-MEMDEP-NEXT: [[L1:%.*]] = phi i32 [ [[L0]], %[[ENTRY]] ], [ [[L1_PRE:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; BE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE]] ] -; BE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans6, %[[LATCH:.*]]), [label %latch] -; BE-MEMDEP: [[LATCH]]: -; BE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; BE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[X]], i32 [[IV_NEXT]] -; BE-MEMDEP-NEXT: [[L1_PRE]] = load i32, ptr [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT]], align 4 -; BE-MEMDEP-NEXT: br label %[[HEADER]] -; BE-MEMDEP: [[EXIT]]: -; BE-MEMDEP-NEXT: ret i32 [[L1]] -; -; BE-MEMSSA-LABEL: define i32 @phi_trans6( -; BE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; BE-MEMSSA: [[HEADER]]: -; BE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; BE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans6, %[[LATCH]]), [label %latch] -; BE-MEMSSA: [[LATCH]]: -; BE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[IV]] -; BE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; BE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; BE-MEMSSA: [[EXIT]]: -; BE-MEMSSA-NEXT: ret i32 [[L1]] +; CHECK-LABEL: define i32 @phi_trans6( +; CHECK-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 +; CHECK-NEXT: call void @use_i32(i32 [[L0]]) +; CHECK-NEXT: br label %[[HEADER:.*]] +; CHECK: [[HEADER]]: +; CHECK-NEXT: [[L1:%.*]] = phi i32 [ [[L0]], %[[ENTRY]] ], [ [[L1_PRE:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE]] ] +; CHECK-NEXT: indirectbr ptr blockaddress(@phi_trans6, %[[LATCH:.*]]), [label %latch] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] +; CHECK: [[LATCH_HEADER_CRIT_EDGE]]: +; CHECK-NEXT: [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[X]], i32 [[IV_NEXT]] +; CHECK-NEXT: [[L1_PRE]] = load i32, ptr [[GEP_1_PHI_TRANS_INSERT_PHI_TRANS_INSERT]], align 4 +; CHECK-NEXT: br label %[[HEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret i32 [[L1]] ; entry: %l0 = load i32, ptr %x @@ -1592,81 +841,25 @@ exit: ; FIXME: Currently we fail to translate the PHI in this case. define i32 @phi_trans7(ptr noalias nocapture readonly %x, i1 %cond) { -; LE-MEMDEP-LABEL: define i32 @phi_trans7( -; LE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; LE-MEMDEP: [[HEADER]]: -; LE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; LE-MEMDEP-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; LE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans7, %[[LATCH:.*]]), [label %latch] -; LE-MEMDEP: [[LATCH]]: -; LE-MEMDEP-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; LE-MEMDEP-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; LE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; LE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: br label %[[HEADER]] -; LE-MEMDEP: [[EXIT]]: -; LE-MEMDEP-NEXT: ret i32 [[L1]] -; -; LE-MEMSSA-LABEL: define i32 @phi_trans7( -; LE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; LE-MEMSSA: [[HEADER]]: -; LE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; LE-MEMSSA-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; LE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans7, %[[LATCH]]), [label %latch] -; LE-MEMSSA: [[LATCH]]: -; LE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; LE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; LE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; LE-MEMSSA: [[EXIT]]: -; LE-MEMSSA-NEXT: ret i32 [[L1]] -; -; BE-MEMDEP-LABEL: define i32 @phi_trans7( -; BE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; BE-MEMDEP: [[HEADER]]: -; BE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; BE-MEMDEP-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; BE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans7, %[[LATCH:.*]]), [label %latch] -; BE-MEMDEP: [[LATCH]]: -; BE-MEMDEP-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; BE-MEMDEP-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; BE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; BE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: br label %[[HEADER]] -; BE-MEMDEP: [[EXIT]]: -; BE-MEMDEP-NEXT: ret i32 [[L1]] -; -; BE-MEMSSA-LABEL: define i32 @phi_trans7( -; BE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; BE-MEMSSA: [[HEADER]]: -; BE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; BE-MEMSSA-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; BE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans7, %[[LATCH]]), [label %latch] -; BE-MEMSSA: [[LATCH]]: -; BE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; BE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; BE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; BE-MEMSSA: [[EXIT]]: -; BE-MEMSSA-NEXT: ret i32 [[L1]] +; CHECK-LABEL: define i32 @phi_trans7( +; CHECK-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 +; CHECK-NEXT: call void @use_i32(i32 [[L0]]) +; CHECK-NEXT: br label %[[HEADER:.*]] +; CHECK: [[HEADER]]: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] +; CHECK-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 +; CHECK-NEXT: indirectbr ptr blockaddress(@phi_trans7, %[[LATCH:.*]]), [label %latch] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] +; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] +; CHECK: [[LATCH_HEADER_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[HEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret i32 [[L1]] ; entry: %l0 = load i32, ptr %x @@ -1690,81 +883,25 @@ exit: ; FIXME: Currently we fail to translate the PHI in this case. define i32 @phi_trans8(ptr noalias nocapture readonly %x, i1 %cond) { -; LE-MEMDEP-LABEL: define i32 @phi_trans8( -; LE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; LE-MEMDEP: [[HEADER]]: -; LE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; LE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans8, %[[LATCH:.*]]), [label %latch] -; LE-MEMDEP: [[LATCH]]: -; LE-MEMDEP-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; LE-MEMDEP-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; LE-MEMDEP-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; LE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; LE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: br label %[[HEADER]] -; LE-MEMDEP: [[EXIT]]: -; LE-MEMDEP-NEXT: ret i32 [[L1]] -; -; LE-MEMSSA-LABEL: define i32 @phi_trans8( -; LE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; LE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; LE-MEMSSA: [[HEADER]]: -; LE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; LE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans8, %[[LATCH]]), [label %latch] -; LE-MEMSSA: [[LATCH]]: -; LE-MEMSSA-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; LE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; LE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; LE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; LE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; LE-MEMSSA: [[EXIT]]: -; LE-MEMSSA-NEXT: ret i32 [[L1]] -; -; BE-MEMDEP-LABEL: define i32 @phi_trans8( -; BE-MEMDEP-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMDEP-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMDEP-NEXT: br label %[[HEADER:.*]] -; BE-MEMDEP: [[HEADER]]: -; BE-MEMDEP-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] -; BE-MEMDEP-NEXT: indirectbr ptr blockaddress(@phi_trans8, %[[LATCH:.*]]), [label %latch] -; BE-MEMDEP: [[LATCH]]: -; BE-MEMDEP-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; BE-MEMDEP-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; BE-MEMDEP-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; BE-MEMDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMDEP-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] -; BE-MEMDEP: [[LATCH_HEADER_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: br label %[[HEADER]] -; BE-MEMDEP: [[EXIT]]: -; BE-MEMDEP-NEXT: ret i32 [[L1]] -; -; BE-MEMSSA-LABEL: define i32 @phi_trans8( -; BE-MEMSSA-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMSSA-NEXT: call void @use_i32(i32 [[L0]]) -; BE-MEMSSA-NEXT: br label %[[HEADER:.*]] -; BE-MEMSSA: [[HEADER]]: -; BE-MEMSSA-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] -; BE-MEMSSA-NEXT: indirectbr ptr blockaddress(@phi_trans8, %[[LATCH]]), [label %latch] -; BE-MEMSSA: [[LATCH]]: -; BE-MEMSSA-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 -; BE-MEMSSA-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] -; BE-MEMSSA-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 -; BE-MEMSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 -; BE-MEMSSA-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[HEADER]] -; BE-MEMSSA: [[EXIT]]: -; BE-MEMSSA-NEXT: ret i32 [[L1]] +; CHECK-LABEL: define i32 @phi_trans8( +; CHECK-SAME: ptr noalias readonly captures(none) [[X:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[L0:%.*]] = load i32, ptr [[X]], align 4 +; CHECK-NEXT: call void @use_i32(i32 [[L0]]) +; CHECK-NEXT: br label %[[HEADER:.*]] +; CHECK: [[HEADER]]: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 2, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH_HEADER_CRIT_EDGE:.*]] ] +; CHECK-NEXT: indirectbr ptr blockaddress(@phi_trans8, %[[LATCH:.*]]), [label %latch] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[OFFSET:%.*]] = add i32 [[IV]], -2 +; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[X]], i32 [[OFFSET]] +; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP_1]], align 4 +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: br i1 [[COND]], label %[[EXIT:.*]], label %[[LATCH_HEADER_CRIT_EDGE]] +; CHECK: [[LATCH_HEADER_CRIT_EDGE]]: +; CHECK-NEXT: br label %[[HEADER]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret i32 [[L1]] ; entry: %l0 = load i32, ptr %x @@ -1790,35 +927,12 @@ exit: ; PR6642 define i32 @memset_to_load() nounwind readnone { -; LE-MEMDEP-LABEL: define i32 @memset_to_load( -; LE-MEMDEP-SAME: ) #[[ATTR2:[0-9]+]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: [[X:%.*]] = alloca [256 x i32], align 4 -; LE-MEMDEP-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[X]], i8 0, i64 1024, i1 false) -; LE-MEMDEP-NEXT: ret i32 0 -; -; LE-MEMSSA-LABEL: define i32 @memset_to_load( -; LE-MEMSSA-SAME: ) #[[ATTR2:[0-9]+]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: [[X:%.*]] = alloca [256 x i32], align 4 -; LE-MEMSSA-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[X]], i8 0, i64 1024, i1 false) -; LE-MEMSSA-NEXT: [[TTMP1:%.*]] = load i32, ptr [[X]], align 4 -; LE-MEMSSA-NEXT: ret i32 [[TTMP1]] -; -; BE-MEMDEP-LABEL: define i32 @memset_to_load( -; BE-MEMDEP-SAME: ) #[[ATTR2:[0-9]+]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: [[X:%.*]] = alloca [256 x i32], align 4 -; BE-MEMDEP-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[X]], i8 0, i64 1024, i1 false) -; BE-MEMDEP-NEXT: ret i32 0 -; -; BE-MEMSSA-LABEL: define i32 @memset_to_load( -; BE-MEMSSA-SAME: ) #[[ATTR2:[0-9]+]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: [[X:%.*]] = alloca [256 x i32], align 4 -; BE-MEMSSA-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[X]], i8 0, i64 1024, i1 false) -; BE-MEMSSA-NEXT: [[TTMP1:%.*]] = load i32, ptr [[X]], align 4 -; BE-MEMSSA-NEXT: ret i32 [[TTMP1]] +; CHECK-LABEL: define i32 @memset_to_load( +; CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[X:%.*]] = alloca [256 x i32], align 4 +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[X]], i8 0, i64 1024, i1 false) +; CHECK-NEXT: ret i32 0 ; entry: %x = alloca [256 x i32], align 4 ; [#uses=2] @@ -1834,45 +948,25 @@ entry: ;;===----------------------------------------------------------------------===;; define i32 @load_load_partial_alias(ptr %P) nounwind ssp { -; LE-MEMDEP-LABEL: define i32 @load_load_partial_alias( -; LE-MEMDEP-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i32 [[TTMP2]], 8 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 -; LE-MEMDEP-NEXT: [[CONV:%.*]] = zext i8 [[TMP1]] to i32 -; LE-MEMDEP-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] -; LE-MEMDEP-NEXT: ret i32 [[ADD]] -; -; LE-MEMSSA-LABEL: define i32 @load_load_partial_alias( -; LE-MEMSSA-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 -; LE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ADD_PTR]], align 1 -; LE-MEMSSA-NEXT: [[CONV:%.*]] = zext i8 [[TTMP5]] to i32 -; LE-MEMSSA-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] -; LE-MEMSSA-NEXT: ret i32 [[ADD]] -; -; BE-MEMDEP-LABEL: define i32 @load_load_partial_alias( -; BE-MEMDEP-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i32 [[TTMP2]], 16 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 -; BE-MEMDEP-NEXT: [[CONV:%.*]] = zext i8 [[TMP1]] to i32 -; BE-MEMDEP-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] -; BE-MEMDEP-NEXT: ret i32 [[ADD]] -; -; BE-MEMSSA-LABEL: define i32 @load_load_partial_alias( -; BE-MEMSSA-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 -; BE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ADD_PTR]], align 1 -; BE-MEMSSA-NEXT: [[CONV:%.*]] = zext i8 [[TTMP5]] to i32 -; BE-MEMSSA-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] -; BE-MEMSSA-NEXT: ret i32 [[ADD]] +; LE-LABEL: define i32 @load_load_partial_alias( +; LE-SAME: ptr [[P:%.*]]) #[[ATTR0]] { +; LE-NEXT: [[ENTRY:.*:]] +; LE-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 +; LE-NEXT: [[TMP0:%.*]] = lshr i32 [[TTMP2]], 8 +; LE-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; LE-NEXT: [[CONV:%.*]] = zext i8 [[TMP1]] to i32 +; LE-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] +; LE-NEXT: ret i32 [[ADD]] +; +; BE-LABEL: define i32 @load_load_partial_alias( +; BE-SAME: ptr [[P:%.*]]) #[[ATTR0]] { +; BE-NEXT: [[ENTRY:.*:]] +; BE-NEXT: [[TTMP2:%.*]] = load i32, ptr [[P]], align 4 +; BE-NEXT: [[TMP0:%.*]] = lshr i32 [[TTMP2]], 16 +; BE-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; BE-NEXT: [[CONV:%.*]] = zext i8 [[TMP1]] to i32 +; BE-NEXT: [[ADD:%.*]] = add nsw i32 [[TTMP2]], [[CONV]] +; BE-NEXT: ret i32 [[ADD]] ; entry: %ttmp2 = load i32, ptr %P @@ -1886,61 +980,33 @@ entry: ; Cross block partial alias case. define i32 @load_load_partial_alias_cross_block(ptr %P) nounwind ssp { -; LE-MEMDEP-LABEL: define i32 @load_load_partial_alias_cross_block( -; LE-MEMDEP-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; LE-MEMDEP-NEXT: [[ENTRY:.*:]] -; LE-MEMDEP-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 -; LE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 8 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 -; LE-MEMDEP-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] -; LE-MEMDEP: [[LAND_LHS_TRUE]]: -; LE-MEMDEP-NEXT: [[CONV6:%.*]] = zext i8 [[TMP1]] to i32 -; LE-MEMDEP-NEXT: ret i32 [[CONV6]] -; LE-MEMDEP: [[IF_END]]: -; LE-MEMDEP-NEXT: ret i32 52 -; -; LE-MEMSSA-LABEL: define i32 @load_load_partial_alias_cross_block( -; LE-MEMSSA-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; LE-MEMSSA-NEXT: [[ENTRY:.*:]] -; LE-MEMSSA-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 -; LE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 -; LE-MEMSSA-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] -; LE-MEMSSA: [[LAND_LHS_TRUE]]: -; LE-MEMSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 -; LE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1 -; LE-MEMSSA-NEXT: [[CONV6:%.*]] = zext i8 [[TTMP5]] to i32 -; LE-MEMSSA-NEXT: ret i32 [[CONV6]] -; LE-MEMSSA: [[IF_END]]: -; LE-MEMSSA-NEXT: ret i32 52 -; -; BE-MEMDEP-LABEL: define i32 @load_load_partial_alias_cross_block( -; BE-MEMDEP-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; BE-MEMDEP-NEXT: [[ENTRY:.*:]] -; BE-MEMDEP-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 -; BE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 16 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 -; BE-MEMDEP-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] -; BE-MEMDEP: [[LAND_LHS_TRUE]]: -; BE-MEMDEP-NEXT: [[CONV6:%.*]] = zext i8 [[TMP1]] to i32 -; BE-MEMDEP-NEXT: ret i32 [[CONV6]] -; BE-MEMDEP: [[IF_END]]: -; BE-MEMDEP-NEXT: ret i32 52 -; -; BE-MEMSSA-LABEL: define i32 @load_load_partial_alias_cross_block( -; BE-MEMSSA-SAME: ptr [[P:%.*]]) #[[ATTR0]] { -; BE-MEMSSA-NEXT: [[ENTRY:.*:]] -; BE-MEMSSA-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 -; BE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 -; BE-MEMSSA-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] -; BE-MEMSSA: [[LAND_LHS_TRUE]]: -; BE-MEMSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 -; BE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1 -; BE-MEMSSA-NEXT: [[CONV6:%.*]] = zext i8 [[TTMP5]] to i32 -; BE-MEMSSA-NEXT: ret i32 [[CONV6]] -; BE-MEMSSA: [[IF_END]]: -; BE-MEMSSA-NEXT: ret i32 52 +; LE-LABEL: define i32 @load_load_partial_alias_cross_block( +; LE-SAME: ptr [[P:%.*]]) #[[ATTR0]] { +; LE-NEXT: [[ENTRY:.*:]] +; LE-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 +; LE-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 +; LE-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 8 +; LE-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; LE-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] +; LE: [[LAND_LHS_TRUE]]: +; LE-NEXT: [[CONV6:%.*]] = zext i8 [[TMP1]] to i32 +; LE-NEXT: ret i32 [[CONV6]] +; LE: [[IF_END]]: +; LE-NEXT: ret i32 52 +; +; BE-LABEL: define i32 @load_load_partial_alias_cross_block( +; BE-SAME: ptr [[P:%.*]]) #[[ATTR0]] { +; BE-NEXT: [[ENTRY:.*:]] +; BE-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 +; BE-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 +; BE-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 16 +; BE-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; BE-NEXT: br i1 [[CMP]], label %[[LAND_LHS_TRUE:.*]], label %[[IF_END:.*]] +; BE: [[LAND_LHS_TRUE]]: +; BE-NEXT: [[CONV6:%.*]] = zext i8 [[TMP1]] to i32 +; BE-NEXT: ret i32 [[CONV6]] +; BE: [[IF_END]]: +; BE-NEXT: ret i32 52 ; entry: %x1 = load i32, ptr %P, align 4 @@ -1984,15 +1050,17 @@ define i32 @load_load_partial_alias_cross_block_phi_trans(ptr %P) nounwind { ; LE-MEMSSA-NEXT: [[ENTRY:.*:]] ; LE-MEMSSA-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 ; LE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 +; LE-MEMSSA-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 8 +; LE-MEMSSA-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; LE-MEMSSA-NEXT: [[TMP2:%.*]] = lshr i32 [[X1]], 16 +; LE-MEMSSA-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 ; LE-MEMSSA-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]] ; LE-MEMSSA: [[IF]]: ; LE-MEMSSA-NEXT: br label %[[JOIN:.*]] ; LE-MEMSSA: [[ELSE]]: ; LE-MEMSSA-NEXT: br label %[[JOIN]] ; LE-MEMSSA: [[JOIN]]: -; LE-MEMSSA-NEXT: [[IDX:%.*]] = phi i64 [ 1, %[[IF]] ], [ 2, %[[ELSE]] ] -; LE-MEMSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[IDX]] -; LE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1 +; LE-MEMSSA-NEXT: [[TTMP5:%.*]] = phi i8 [ [[TMP1]], %[[IF]] ], [ [[TMP3]], %[[ELSE]] ] ; LE-MEMSSA-NEXT: [[CONV6:%.*]] = zext i8 [[TTMP5]] to i32 ; LE-MEMSSA-NEXT: ret i32 [[CONV6]] ; LE-MEMSSA: [[IF_END:.*:]] @@ -2024,15 +1092,17 @@ define i32 @load_load_partial_alias_cross_block_phi_trans(ptr %P) nounwind { ; BE-MEMSSA-NEXT: [[ENTRY:.*:]] ; BE-MEMSSA-NEXT: [[X1:%.*]] = load i32, ptr [[P]], align 4 ; BE-MEMSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[X1]], 127 +; BE-MEMSSA-NEXT: [[TMP0:%.*]] = lshr i32 [[X1]], 16 +; BE-MEMSSA-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; BE-MEMSSA-NEXT: [[TMP2:%.*]] = lshr i32 [[X1]], 8 +; BE-MEMSSA-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 ; BE-MEMSSA-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[ELSE:.*]] ; BE-MEMSSA: [[IF]]: ; BE-MEMSSA-NEXT: br label %[[JOIN:.*]] ; BE-MEMSSA: [[ELSE]]: ; BE-MEMSSA-NEXT: br label %[[JOIN]] ; BE-MEMSSA: [[JOIN]]: -; BE-MEMSSA-NEXT: [[IDX:%.*]] = phi i64 [ 1, %[[IF]] ], [ 2, %[[ELSE]] ] -; BE-MEMSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[IDX]] -; BE-MEMSSA-NEXT: [[TTMP5:%.*]] = load i8, ptr [[ARRAYIDX4]], align 1 +; BE-MEMSSA-NEXT: [[TTMP5:%.*]] = phi i8 [ [[TMP1]], %[[IF]] ], [ [[TMP3]], %[[ELSE]] ] ; BE-MEMSSA-NEXT: [[CONV6:%.*]] = zext i8 [[TTMP5]] to i32 ; BE-MEMSSA-NEXT: ret i32 [[CONV6]] ; BE-MEMSSA: [[IF_END:.*:]] @@ -2063,104 +1133,60 @@ if.end: } define void @load_load_partial_alias_loop(ptr %P) { -; LE-MEMDEP-LABEL: define void @load_load_partial_alias_loop( -; LE-MEMDEP-SAME: ptr [[P:%.*]]) { -; LE-MEMDEP-NEXT: [[ENTRY:.*]]: -; LE-MEMDEP-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 -; LE-MEMDEP-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 -; LE-MEMDEP-NEXT: call void @use.i8(i8 [[V_1]]) -; LE-MEMDEP-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 -; LE-MEMDEP-NEXT: call void @use.i32(i32 [[V_1_32]]) -; LE-MEMDEP-NEXT: [[TMP0:%.*]] = trunc i32 [[V_1_32]] to i8 -; LE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; LE-MEMDEP: [[LOOP]]: -; LE-MEMDEP-NEXT: [[V_I:%.*]] = phi i8 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP2:%.*]], %[[LOOP_LOOP_CRIT_EDGE:.*]] ] -; LE-MEMDEP-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_LOOP_CRIT_EDGE]] ] -; LE-MEMDEP-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] -; LE-MEMDEP-NEXT: call void @use.i8(i8 [[V_I]]) -; LE-MEMDEP-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 -; LE-MEMDEP-NEXT: call void @use.i32(i32 [[V_I_32]]) -; LE-MEMDEP-NEXT: [[I_INC]] = add i64 [[I]], 1 -; LE-MEMDEP-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = lshr i32 [[V_I_32]], 8 -; LE-MEMDEP-NEXT: [[TMP2]] = trunc i32 [[TMP1]] to i8 -; LE-MEMDEP-NEXT: br i1 [[CMP]], label %[[LOOP_LOOP_CRIT_EDGE]], label %[[EXIT:.*]] -; LE-MEMDEP: [[LOOP_LOOP_CRIT_EDGE]]: -; LE-MEMDEP-NEXT: br label %[[LOOP]] -; LE-MEMDEP: [[EXIT]]: -; LE-MEMDEP-NEXT: ret void -; -; LE-MEMSSA-LABEL: define void @load_load_partial_alias_loop( -; LE-MEMSSA-SAME: ptr [[P:%.*]]) { -; LE-MEMSSA-NEXT: [[ENTRY:.*]]: -; LE-MEMSSA-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 -; LE-MEMSSA-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 -; LE-MEMSSA-NEXT: call void @use.i8(i8 [[V_1]]) -; LE-MEMSSA-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 -; LE-MEMSSA-NEXT: call void @use.i32(i32 [[V_1_32]]) -; LE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; LE-MEMSSA: [[LOOP]]: -; LE-MEMSSA-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP]] ] -; LE-MEMSSA-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] -; LE-MEMSSA-NEXT: [[V_I:%.*]] = load i8, ptr [[P_I]], align 1 -; LE-MEMSSA-NEXT: call void @use.i8(i8 [[V_I]]) -; LE-MEMSSA-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 -; LE-MEMSSA-NEXT: call void @use.i32(i32 [[V_I_32]]) -; LE-MEMSSA-NEXT: [[I_INC]] = add i64 [[I]], 1 -; LE-MEMSSA-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 -; LE-MEMSSA-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] -; LE-MEMSSA: [[EXIT]]: -; LE-MEMSSA-NEXT: ret void -; -; BE-MEMDEP-LABEL: define void @load_load_partial_alias_loop( -; BE-MEMDEP-SAME: ptr [[P:%.*]]) { -; BE-MEMDEP-NEXT: [[ENTRY:.*]]: -; BE-MEMDEP-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 -; BE-MEMDEP-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 -; BE-MEMDEP-NEXT: call void @use.i8(i8 [[V_1]]) -; BE-MEMDEP-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 -; BE-MEMDEP-NEXT: call void @use.i32(i32 [[V_1_32]]) -; BE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i32 [[V_1_32]], 24 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 -; BE-MEMDEP-NEXT: br label %[[LOOP:.*]] -; BE-MEMDEP: [[LOOP]]: -; BE-MEMDEP-NEXT: [[V_I:%.*]] = phi i8 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[LOOP_LOOP_CRIT_EDGE:.*]] ] -; BE-MEMDEP-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_LOOP_CRIT_EDGE]] ] -; BE-MEMDEP-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] -; BE-MEMDEP-NEXT: call void @use.i8(i8 [[V_I]]) -; BE-MEMDEP-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 -; BE-MEMDEP-NEXT: call void @use.i32(i32 [[V_I_32]]) -; BE-MEMDEP-NEXT: [[I_INC]] = add i64 [[I]], 1 -; BE-MEMDEP-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 -; BE-MEMDEP-NEXT: [[TMP2:%.*]] = lshr i32 [[V_I_32]], 16 -; BE-MEMDEP-NEXT: [[TMP3]] = trunc i32 [[TMP2]] to i8 -; BE-MEMDEP-NEXT: br i1 [[CMP]], label %[[LOOP_LOOP_CRIT_EDGE]], label %[[EXIT:.*]] -; BE-MEMDEP: [[LOOP_LOOP_CRIT_EDGE]]: -; BE-MEMDEP-NEXT: br label %[[LOOP]] -; BE-MEMDEP: [[EXIT]]: -; BE-MEMDEP-NEXT: ret void -; -; BE-MEMSSA-LABEL: define void @load_load_partial_alias_loop( -; BE-MEMSSA-SAME: ptr [[P:%.*]]) { -; BE-MEMSSA-NEXT: [[ENTRY:.*]]: -; BE-MEMSSA-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 -; BE-MEMSSA-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 -; BE-MEMSSA-NEXT: call void @use.i8(i8 [[V_1]]) -; BE-MEMSSA-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 -; BE-MEMSSA-NEXT: call void @use.i32(i32 [[V_1_32]]) -; BE-MEMSSA-NEXT: br label %[[LOOP:.*]] -; BE-MEMSSA: [[LOOP]]: -; BE-MEMSSA-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP]] ] -; BE-MEMSSA-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] -; BE-MEMSSA-NEXT: [[V_I:%.*]] = load i8, ptr [[P_I]], align 1 -; BE-MEMSSA-NEXT: call void @use.i8(i8 [[V_I]]) -; BE-MEMSSA-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 -; BE-MEMSSA-NEXT: call void @use.i32(i32 [[V_I_32]]) -; BE-MEMSSA-NEXT: [[I_INC]] = add i64 [[I]], 1 -; BE-MEMSSA-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 -; BE-MEMSSA-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]] -; BE-MEMSSA: [[EXIT]]: -; BE-MEMSSA-NEXT: ret void +; LE-LABEL: define void @load_load_partial_alias_loop( +; LE-SAME: ptr [[P:%.*]]) { +; LE-NEXT: [[ENTRY:.*]]: +; LE-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 +; LE-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 +; LE-NEXT: call void @use.i8(i8 [[V_1]]) +; LE-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 +; LE-NEXT: call void @use.i32(i32 [[V_1_32]]) +; LE-NEXT: [[TMP0:%.*]] = trunc i32 [[V_1_32]] to i8 +; LE-NEXT: br label %[[LOOP:.*]] +; LE: [[LOOP]]: +; LE-NEXT: [[V_I:%.*]] = phi i8 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP2:%.*]], %[[LOOP_LOOP_CRIT_EDGE:.*]] ] +; LE-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_LOOP_CRIT_EDGE]] ] +; LE-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] +; LE-NEXT: call void @use.i8(i8 [[V_I]]) +; LE-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 +; LE-NEXT: call void @use.i32(i32 [[V_I_32]]) +; LE-NEXT: [[I_INC]] = add i64 [[I]], 1 +; LE-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 +; LE-NEXT: [[TMP1:%.*]] = lshr i32 [[V_I_32]], 8 +; LE-NEXT: [[TMP2]] = trunc i32 [[TMP1]] to i8 +; LE-NEXT: br i1 [[CMP]], label %[[LOOP_LOOP_CRIT_EDGE]], label %[[EXIT:.*]] +; LE: [[LOOP_LOOP_CRIT_EDGE]]: +; LE-NEXT: br label %[[LOOP]] +; LE: [[EXIT]]: +; LE-NEXT: ret void +; +; BE-LABEL: define void @load_load_partial_alias_loop( +; BE-SAME: ptr [[P:%.*]]) { +; BE-NEXT: [[ENTRY:.*]]: +; BE-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i64 1 +; BE-NEXT: [[V_1:%.*]] = load i8, ptr [[P_1]], align 1 +; BE-NEXT: call void @use.i8(i8 [[V_1]]) +; BE-NEXT: [[V_1_32:%.*]] = load i32, ptr [[P_1]], align 4 +; BE-NEXT: call void @use.i32(i32 [[V_1_32]]) +; BE-NEXT: [[TMP0:%.*]] = lshr i32 [[V_1_32]], 24 +; BE-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; BE-NEXT: br label %[[LOOP:.*]] +; BE: [[LOOP]]: +; BE-NEXT: [[V_I:%.*]] = phi i8 [ [[TMP1]], %[[ENTRY]] ], [ [[TMP3:%.*]], %[[LOOP_LOOP_CRIT_EDGE:.*]] ] +; BE-NEXT: [[I:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[I_INC:%.*]], %[[LOOP_LOOP_CRIT_EDGE]] ] +; BE-NEXT: [[P_I:%.*]] = getelementptr i8, ptr [[P]], i64 [[I]] +; BE-NEXT: call void @use.i8(i8 [[V_I]]) +; BE-NEXT: [[V_I_32:%.*]] = load i32, ptr [[P_I]], align 4 +; BE-NEXT: call void @use.i32(i32 [[V_I_32]]) +; BE-NEXT: [[I_INC]] = add i64 [[I]], 1 +; BE-NEXT: [[CMP:%.*]] = icmp ne i64 [[I_INC]], 64 +; BE-NEXT: [[TMP2:%.*]] = lshr i32 [[V_I_32]], 16 +; BE-NEXT: [[TMP3]] = trunc i32 [[TMP2]] to i8 +; BE-NEXT: br i1 [[CMP]], label %[[LOOP_LOOP_CRIT_EDGE]], label %[[EXIT:.*]] +; BE: [[LOOP_LOOP_CRIT_EDGE]]: +; BE-NEXT: br label %[[LOOP]] +; BE: [[EXIT]]: +; BE-NEXT: ret void ; entry: %P.1 = getelementptr i8, ptr %P, i64 1 @@ -2191,63 +1217,39 @@ declare void @use.i32(i32) readnone @global = external local_unnamed_addr global i8, align 4 define void @load_load_partial_alias_atomic(ptr %arg) { -; LE-MEMDEP-LABEL: define void @load_load_partial_alias_atomic( -; LE-MEMDEP-SAME: ptr [[ARG:%.*]]) { -; LE-MEMDEP-NEXT: [[BB:.*]]: -; LE-MEMDEP-NEXT: [[TMP2_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 1 -; LE-MEMDEP-NEXT: [[TMP2_3:%.*]] = load i64, ptr [[TMP2_1]], align 4 -; LE-MEMDEP-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 -; LE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i64 [[TMP2_3]], 8 -; LE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i8 -; LE-MEMDEP-NEXT: br label %[[BB5:.*]] -; LE-MEMDEP: [[BB5]]: -; LE-MEMDEP-NEXT: [[TMP4_1:%.*]] = phi i8 [ [[TMP4_1_PRE:%.*]], %[[BB5]] ], [ [[TMP1]], %[[BB]] ] -; LE-MEMDEP-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 -; LE-MEMDEP-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] -; LE-MEMDEP-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 -; LE-MEMDEP-NEXT: [[TMP4_1_PRE]] = load i8, ptr [[TMP3_1]], align 4 -; LE-MEMDEP-NEXT: br label %[[BB5]] -; -; LE-MEMSSA-LABEL: define void @load_load_partial_alias_atomic( -; LE-MEMSSA-SAME: ptr [[ARG:%.*]]) { -; LE-MEMSSA-NEXT: [[BB:.*:]] -; LE-MEMSSA-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 -; LE-MEMSSA-NEXT: br label %[[BB5:.*]] -; LE-MEMSSA: [[BB5]]: -; LE-MEMSSA-NEXT: [[TMP4_1:%.*]] = load i8, ptr [[TMP3_1]], align 4 -; LE-MEMSSA-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 -; LE-MEMSSA-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] -; LE-MEMSSA-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 -; LE-MEMSSA-NEXT: br label %[[BB5]] -; -; BE-MEMDEP-LABEL: define void @load_load_partial_alias_atomic( -; BE-MEMDEP-SAME: ptr [[ARG:%.*]]) { -; BE-MEMDEP-NEXT: [[BB:.*]]: -; BE-MEMDEP-NEXT: [[TMP2_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 1 -; BE-MEMDEP-NEXT: [[TMP2_3:%.*]] = load i64, ptr [[TMP2_1]], align 4 -; BE-MEMDEP-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 -; BE-MEMDEP-NEXT: [[TMP0:%.*]] = lshr i64 [[TMP2_3]], 48 -; BE-MEMDEP-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i8 -; BE-MEMDEP-NEXT: br label %[[BB5:.*]] -; BE-MEMDEP: [[BB5]]: -; BE-MEMDEP-NEXT: [[TMP4_1:%.*]] = phi i8 [ [[TMP4_1_PRE:%.*]], %[[BB5]] ], [ [[TMP1]], %[[BB]] ] -; BE-MEMDEP-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 -; BE-MEMDEP-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] -; BE-MEMDEP-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 -; BE-MEMDEP-NEXT: [[TMP4_1_PRE]] = load i8, ptr [[TMP3_1]], align 4 -; BE-MEMDEP-NEXT: br label %[[BB5]] -; -; BE-MEMSSA-LABEL: define void @load_load_partial_alias_atomic( -; BE-MEMSSA-SAME: ptr [[ARG:%.*]]) { -; BE-MEMSSA-NEXT: [[BB:.*:]] -; BE-MEMSSA-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 -; BE-MEMSSA-NEXT: br label %[[BB5:.*]] -; BE-MEMSSA: [[BB5]]: -; BE-MEMSSA-NEXT: [[TMP4_1:%.*]] = load i8, ptr [[TMP3_1]], align 4 -; BE-MEMSSA-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 -; BE-MEMSSA-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] -; BE-MEMSSA-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 -; BE-MEMSSA-NEXT: br label %[[BB5]] +; LE-LABEL: define void @load_load_partial_alias_atomic( +; LE-SAME: ptr [[ARG:%.*]]) { +; LE-NEXT: [[BB:.*]]: +; LE-NEXT: [[TMP2_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 1 +; LE-NEXT: [[TMP2_3:%.*]] = load i64, ptr [[TMP2_1]], align 4 +; LE-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 +; LE-NEXT: [[TMP0:%.*]] = lshr i64 [[TMP2_3]], 8 +; LE-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i8 +; LE-NEXT: br label %[[BB5:.*]] +; LE: [[BB5]]: +; LE-NEXT: [[TMP4_1:%.*]] = phi i8 [ [[TMP4_1_PRE:%.*]], %[[BB5]] ], [ [[TMP1]], %[[BB]] ] +; LE-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 +; LE-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] +; LE-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 +; LE-NEXT: [[TMP4_1_PRE]] = load i8, ptr [[TMP3_1]], align 4 +; LE-NEXT: br label %[[BB5]] +; +; BE-LABEL: define void @load_load_partial_alias_atomic( +; BE-SAME: ptr [[ARG:%.*]]) { +; BE-NEXT: [[BB:.*]]: +; BE-NEXT: [[TMP2_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 1 +; BE-NEXT: [[TMP2_3:%.*]] = load i64, ptr [[TMP2_1]], align 4 +; BE-NEXT: [[TMP3_1:%.*]] = getelementptr inbounds i8, ptr [[ARG]], i64 2 +; BE-NEXT: [[TMP0:%.*]] = lshr i64 [[TMP2_3]], 48 +; BE-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i8 +; BE-NEXT: br label %[[BB5:.*]] +; BE: [[BB5]]: +; BE-NEXT: [[TMP4_1:%.*]] = phi i8 [ [[TMP4_1_PRE:%.*]], %[[BB5]] ], [ [[TMP1]], %[[BB]] ] +; BE-NEXT: [[TMP6_1:%.*]] = load atomic i8, ptr @global acquire, align 4 +; BE-NEXT: [[TMP7_1:%.*]] = add i8 [[TMP6_1]], [[TMP4_1]] +; BE-NEXT: store i8 [[TMP7_1]], ptr [[ARG]], align 1 +; BE-NEXT: [[TMP4_1_PRE]] = load i8, ptr [[TMP3_1]], align 4 +; BE-NEXT: br label %[[BB5]] ; bb: %tmp2.1 = getelementptr inbounds i8, ptr %arg, i64 1 @@ -2352,39 +1354,13 @@ declare void @use3(ptr, ptr) ; PR8908 define void @test_escape1() nounwind { -; LE-MEMDEP-LABEL: define void @test_escape1( -; LE-MEMDEP-SAME: ) #[[ATTR3]] { -; LE-MEMDEP-NEXT: [[X:%.*]] = alloca ptr, align 8 -; LE-MEMDEP-NEXT: store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr [[X]], align 8 -; LE-MEMDEP-NEXT: call void @use() #[[ATTR3]] -; LE-MEMDEP-NEXT: call void @use3(ptr [[X]], ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2)) #[[ATTR3]] -; LE-MEMDEP-NEXT: ret void -; -; LE-MEMSSA-LABEL: define void @test_escape1( -; LE-MEMSSA-SAME: ) #[[ATTR3]] { -; LE-MEMSSA-NEXT: [[X:%.*]] = alloca ptr, align 8 -; LE-MEMSSA-NEXT: store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr [[X]], align 8 -; LE-MEMSSA-NEXT: call void @use() #[[ATTR3]] -; LE-MEMSSA-NEXT: [[DEAD:%.*]] = load ptr, ptr [[X]], align 8 -; LE-MEMSSA-NEXT: call void @use3(ptr [[X]], ptr [[DEAD]]) #[[ATTR3]] -; LE-MEMSSA-NEXT: ret void -; -; BE-MEMDEP-LABEL: define void @test_escape1( -; BE-MEMDEP-SAME: ) #[[ATTR3]] { -; BE-MEMDEP-NEXT: [[X:%.*]] = alloca ptr, align 8 -; BE-MEMDEP-NEXT: store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr [[X]], align 8 -; BE-MEMDEP-NEXT: call void @use() #[[ATTR3]] -; BE-MEMDEP-NEXT: call void @use3(ptr [[X]], ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2)) #[[ATTR3]] -; BE-MEMDEP-NEXT: ret void -; -; BE-MEMSSA-LABEL: define void @test_escape1( -; BE-MEMSSA-SAME: ) #[[ATTR3]] { -; BE-MEMSSA-NEXT: [[X:%.*]] = alloca ptr, align 8 -; BE-MEMSSA-NEXT: store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr [[X]], align 8 -; BE-MEMSSA-NEXT: call void @use() #[[ATTR3]] -; BE-MEMSSA-NEXT: [[DEAD:%.*]] = load ptr, ptr [[X]], align 8 -; BE-MEMSSA-NEXT: call void @use3(ptr [[X]], ptr [[DEAD]]) #[[ATTR3]] -; BE-MEMSSA-NEXT: ret void +; CHECK-LABEL: define void @test_escape1( +; CHECK-SAME: ) #[[ATTR3]] { +; CHECK-NEXT: [[X:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr [[X]], align 8 +; CHECK-NEXT: call void @use() #[[ATTR3]] +; CHECK-NEXT: call void @use3(ptr [[X]], ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2)) #[[ATTR3]] +; CHECK-NEXT: ret void ; %x = alloca ptr, align 8 store ptr getelementptr inbounds ([5 x ptr], ptr @_ZTV1X, i64 0, i64 2), ptr %x, align 8 @@ -2393,6 +1369,3 @@ define void @test_escape1() nounwind { call void @use3(ptr %x, ptr %DEAD) nounwind ret void } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; BE: {{.*}} -; LE: {{.*}} diff --git a/llvm/test/Transforms/GVN/nonescaping.ll b/llvm/test/Transforms/GVN/nonescaping.ll index 0866a27b249f5..30f2c0eee4593 100644 --- a/llvm/test/Transforms/GVN/nonescaping.ll +++ b/llvm/test/Transforms/GVN/nonescaping.ll @@ -10,18 +10,10 @@ declare noalias ptr @_Znwm(i64) declare void @escape(ptr) define i8 @test_malloc(ptr %p) { -; MDEP-LABEL: @test_malloc( -; MDEP-NEXT: [[OBJ:%.*]] = call ptr @malloc(i64 16) -; MDEP-NEXT: call void @escape(ptr [[OBJ]]) -; MDEP-NEXT: ret i8 0 -; -; MSSA-LABEL: @test_malloc( -; MSSA-NEXT: [[V1:%.*]] = load i8, ptr [[P:%.*]], align 1 -; MSSA-NEXT: [[OBJ:%.*]] = call ptr @malloc(i64 16) -; MSSA-NEXT: [[V2:%.*]] = load i8, ptr [[P]], align 1 -; MSSA-NEXT: [[SUB:%.*]] = sub i8 [[V1]], [[V2]] -; MSSA-NEXT: call void @escape(ptr [[OBJ]]) -; MSSA-NEXT: ret i8 [[SUB]] +; CHECK-LABEL: @test_malloc( +; CHECK-NEXT: [[OBJ:%.*]] = call ptr @malloc(i64 16) +; CHECK-NEXT: call void @escape(ptr [[OBJ]]) +; CHECK-NEXT: ret i8 0 ; %v1 = load i8, ptr %p %obj = call ptr @malloc(i64 16) @@ -32,18 +24,10 @@ define i8 @test_malloc(ptr %p) { } define i8 @test_calloc(ptr %p) { -; MDEP-LABEL: @test_calloc( -; MDEP-NEXT: [[OBJ:%.*]] = call ptr @calloc(i64 1, i64 16) -; MDEP-NEXT: call void @escape(ptr [[OBJ]]) -; MDEP-NEXT: ret i8 0 -; -; MSSA-LABEL: @test_calloc( -; MSSA-NEXT: [[V1:%.*]] = load i8, ptr [[P:%.*]], align 1 -; MSSA-NEXT: [[OBJ:%.*]] = call ptr @calloc(i64 1, i64 16) -; MSSA-NEXT: [[V2:%.*]] = load i8, ptr [[P]], align 1 -; MSSA-NEXT: [[SUB:%.*]] = sub i8 [[V1]], [[V2]] -; MSSA-NEXT: call void @escape(ptr [[OBJ]]) -; MSSA-NEXT: ret i8 [[SUB]] +; CHECK-LABEL: @test_calloc( +; CHECK-NEXT: [[OBJ:%.*]] = call ptr @calloc(i64 1, i64 16) +; CHECK-NEXT: call void @escape(ptr [[OBJ]]) +; CHECK-NEXT: ret i8 0 ; %v1 = load i8, ptr %p %obj = call ptr @calloc(i64 1, i64 16) @@ -54,18 +38,10 @@ define i8 @test_calloc(ptr %p) { } define i8 @test_opnew(ptr %p) { -; MDEP-LABEL: @test_opnew( -; MDEP-NEXT: [[OBJ:%.*]] = call ptr @_Znwm(i64 16) -; MDEP-NEXT: call void @escape(ptr [[OBJ]]) -; MDEP-NEXT: ret i8 0 -; -; MSSA-LABEL: @test_opnew( -; MSSA-NEXT: [[V1:%.*]] = load i8, ptr [[P:%.*]], align 1 -; MSSA-NEXT: [[OBJ:%.*]] = call ptr @_Znwm(i64 16) -; MSSA-NEXT: [[V2:%.*]] = load i8, ptr [[P]], align 1 -; MSSA-NEXT: [[SUB:%.*]] = sub i8 [[V1]], [[V2]] -; MSSA-NEXT: call void @escape(ptr [[OBJ]]) -; MSSA-NEXT: ret i8 [[SUB]] +; CHECK-LABEL: @test_opnew( +; CHECK-NEXT: [[OBJ:%.*]] = call ptr @_Znwm(i64 16) +; CHECK-NEXT: call void @escape(ptr [[OBJ]]) +; CHECK-NEXT: ret i8 0 ; %v1 = load i8, ptr %p %obj = call ptr @_Znwm(i64 16) @@ -75,4 +51,5 @@ define i8 @test_opnew(ptr %p) { ret i8 %sub } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/pr14166.ll b/llvm/test/Transforms/GVN/pr14166.ll index 6e23bdcf30053..e9d1e4db088bb 100644 --- a/llvm/test/Transforms/GVN/pr14166.ll +++ b/llvm/test/Transforms/GVN/pr14166.ll @@ -3,23 +3,15 @@ ; RUN: opt -disable-basic-aa -passes='gvn' -S < %s | FileCheck --check-prefixes=CHECK,MSSA %s target datalayout = "e-p:32:32:32" define <2 x i32> @test1() { -; MDEP-LABEL: define <2 x i32> @test1() { -; MDEP-NEXT: [[V1:%.*]] = alloca <2 x i32>, align 8 -; MDEP-NEXT: call void @anything(ptr [[V1]]) -; MDEP-NEXT: [[V2:%.*]] = load <2 x i32>, ptr [[V1]], align 8 -; MDEP-NEXT: [[V3:%.*]] = inttoptr <2 x i32> [[V2]] to <2 x ptr> -; MDEP-NEXT: store <2 x ptr> [[V3]], ptr [[V1]], align 8 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to i64 -; MDEP-NEXT: ret <2 x i32> [[V2]] +; CHECK-LABEL: define <2 x i32> @test1() { +; CHECK-NEXT: [[V1:%.*]] = alloca <2 x i32>, align 8 +; CHECK-NEXT: call void @anything(ptr [[V1]]) +; CHECK-NEXT: [[V2:%.*]] = load <2 x i32>, ptr [[V1]], align 8 +; CHECK-NEXT: [[V3:%.*]] = inttoptr <2 x i32> [[V2]] to <2 x ptr> +; CHECK-NEXT: store <2 x ptr> [[V3]], ptr [[V1]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to i64 +; CHECK-NEXT: ret <2 x i32> [[V2]] ; -; MSSA-LABEL: define <2 x i32> @test1() { -; MSSA-NEXT: [[V1:%.*]] = alloca <2 x i32>, align 8 -; MSSA-NEXT: call void @anything(ptr [[V1]]) -; MSSA-NEXT: [[V2:%.*]] = load <2 x i32>, ptr [[V1]], align 8 -; MSSA-NEXT: [[V3:%.*]] = inttoptr <2 x i32> [[V2]] to <2 x ptr> -; MSSA-NEXT: store <2 x ptr> [[V3]], ptr [[V1]], align 8 -; MSSA-NEXT: [[V5:%.*]] = load <2 x i32>, ptr [[V1]], align 8 -; MSSA-NEXT: ret <2 x i32> [[V5]] %v1 = alloca <2 x i32> call void @anything(ptr %v1) %v2 = load <2 x i32>, ptr %v1 @@ -32,4 +24,5 @@ define <2 x i32> @test1() { declare void @anything(ptr) ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/readattrs.ll b/llvm/test/Transforms/GVN/readattrs.ll index 6e02dd36b5749..ac69556060fe5 100644 --- a/llvm/test/Transforms/GVN/readattrs.ll +++ b/llvm/test/Transforms/GVN/readattrs.ll @@ -8,18 +8,11 @@ target triple = "x86_64-unknown-linux-gnu" declare void @use(ptr readonly nocapture) define i8 @test() { -; MDEP-LABEL: define i8 @test() { -; MDEP-NEXT: [[A:%.*]] = alloca i8, align 1 -; MDEP-NEXT: store i8 1, ptr [[A]], align 1 -; MDEP-NEXT: call void @use(ptr [[A]]) -; MDEP-NEXT: ret i8 1 -; -; MSSA-LABEL: define i8 @test() { -; MSSA-NEXT: [[A:%.*]] = alloca i8, align 1 -; MSSA-NEXT: store i8 1, ptr [[A]], align 1 -; MSSA-NEXT: call void @use(ptr [[A]]) -; MSSA-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 1 -; MSSA-NEXT: ret i8 [[B]] +; CHECK-LABEL: define i8 @test() { +; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 +; CHECK-NEXT: store i8 1, ptr [[A]], align 1 +; CHECK-NEXT: call void @use(ptr [[A]]) +; CHECK-NEXT: ret i8 1 ; %a = alloca i8 store i8 1, ptr %a @@ -28,4 +21,5 @@ define i8 @test() { ret i8 %b } ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/setjmp.ll b/llvm/test/Transforms/GVN/setjmp.ll index 5351878419963..14ab9b79db119 100644 --- a/llvm/test/Transforms/GVN/setjmp.ll +++ b/llvm/test/Transforms/GVN/setjmp.ll @@ -38,32 +38,18 @@ if.end: ; We are still allowed to optimize non-volatile accesses to allocas. define i32 @test_alloca() { -; MDEP-LABEL: define i32 @test_alloca() { -; MDEP-NEXT: [[ALLOC:%.*]] = alloca i43, align 8 -; MDEP-NEXT: store i32 10, ptr [[ALLOC]], align 4 -; MDEP-NEXT: [[SJ:%.*]] = call i32 @setjmp() -; MDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0 -; MDEP-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] -; MDEP: [[IF_THEN]]: -; MDEP-NEXT: store i32 20, ptr [[ALLOC]], align 4 -; MDEP-NEXT: call void @longjmp() -; MDEP-NEXT: unreachable -; MDEP: [[IF_END]]: -; MDEP-NEXT: ret i32 10 -; -; MSSA-LABEL: define i32 @test_alloca() { -; MSSA-NEXT: [[ALLOC:%.*]] = alloca i43, align 8 -; MSSA-NEXT: store i32 10, ptr [[ALLOC]], align 4 -; MSSA-NEXT: [[SJ:%.*]] = call i32 @setjmp() -; MSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0 -; MSSA-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] -; MSSA: [[IF_THEN]]: -; MSSA-NEXT: store i32 20, ptr [[ALLOC]], align 4 -; MSSA-NEXT: call void @longjmp() -; MSSA-NEXT: unreachable -; MSSA: [[IF_END]]: -; MSSA-NEXT: [[RES:%.*]] = load i32, ptr [[ALLOC]], align 4 -; MSSA-NEXT: ret i32 [[RES]] +; CHECK-LABEL: define i32 @test_alloca() { +; CHECK-NEXT: [[ALLOC:%.*]] = alloca i43, align 8 +; CHECK-NEXT: store i32 10, ptr [[ALLOC]], align 4 +; CHECK-NEXT: [[SJ:%.*]] = call i32 @setjmp() +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SJ]], 0 +; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: store i32 20, ptr [[ALLOC]], align 4 +; CHECK-NEXT: call void @longjmp() +; CHECK-NEXT: unreachable +; CHECK: [[IF_END]]: +; CHECK-NEXT: ret i32 10 ; %alloc = alloca i43 store i32 10, ptr %alloc, align 4 @@ -111,3 +97,6 @@ if.end: %res = load volatile i32, ptr %alloc ret i32 %res } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}} diff --git a/llvm/test/Transforms/GVN/tbaa.ll b/llvm/test/Transforms/GVN/tbaa.ll index bb9b0dea73ab1..876ab5df50a9a 100644 --- a/llvm/test/Transforms/GVN/tbaa.ll +++ b/llvm/test/Transforms/GVN/tbaa.ll @@ -143,18 +143,10 @@ define i32 @test7(ptr %p, ptr %q) { } define i32 @test8(ptr %p, ptr %q) { -; MDEP-LABEL: define i32 @test8( -; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { -; MDEP-NEXT: store i32 15, ptr [[P]], align 4 -; MDEP-NEXT: ret i32 0 -; -; MSSA-LABEL: define i32 @test8( -; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { -; MSSA-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[NODE_TBAA10:![0-9]+]] -; MSSA-NEXT: store i32 15, ptr [[P]], align 4 -; MSSA-NEXT: [[B:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[NODE_TBAA10]] -; MSSA-NEXT: [[C:%.*]] = sub i32 [[A]], [[B]] -; MSSA-NEXT: ret i32 [[C]] +; CHECK-LABEL: define i32 @test8( +; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { +; CHECK-NEXT: store i32 15, ptr [[P]], align 4 +; CHECK-NEXT: ret i32 0 ; ; Since we know the location is invariant, we can forward the ; load across the potentially aliasing store. @@ -167,18 +159,10 @@ define i32 @test8(ptr %p, ptr %q) { } define i32 @test9(ptr %p, ptr %q) { -; MDEP-LABEL: define i32 @test9( -; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { -; MDEP-NEXT: call void @clobber() -; MDEP-NEXT: ret i32 0 -; -; MSSA-LABEL: define i32 @test9( -; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { -; MSSA-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[NODE_TBAA10]] -; MSSA-NEXT: call void @clobber() -; MSSA-NEXT: [[B:%.*]] = load i32, ptr [[Q]], align 4, !tbaa [[NODE_TBAA10]] -; MSSA-NEXT: [[C:%.*]] = sub i32 [[A]], [[B]] -; MSSA-NEXT: ret i32 [[C]] +; CHECK-LABEL: define i32 @test9( +; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { +; CHECK-NEXT: call void @clobber() +; CHECK-NEXT: ret i32 0 ; ; Since we know the location is invariant, we can forward the ; load across the potentially aliasing store (within the call). @@ -201,8 +185,8 @@ define i32 @test10(ptr %p, ptr %q) { ; ; MSSA-LABEL: define i32 @test10( ; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) { -; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[INT_TBAA13:![0-9]+]] -; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[INT_TBAA17:![0-9]+]] +; MSSA-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[INT_TBAA10:![0-9]+]] +; MSSA-NEXT: [[B:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[INT_TBAA14:![0-9]+]] ; MSSA-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; MSSA-NEXT: ret i32 [[C]] ; @@ -263,15 +247,10 @@ declare i32 @foo(ptr) readonly ; MSSA: [[SCALAR_TYPE_TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0} ; MSSA: [[META8]] = !{!"scalar type", [[META9:![0-9]+]]} ; MSSA: [[META9]] = !{!"another root"} -; MSSA: [[NODE_TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0, i64 1} -; MSSA: [[META11]] = !{!"node", [[META12:![0-9]+]]} -; MSSA: [[META12]] = !{!"yet another root"} -; MSSA: [[INT_TBAA13]] = !{[[META14:![0-9]+]], [[META15:![0-9]+]], i64 0} -; MSSA: [[META14]] = !{!"struct X", [[META15]], i64 0} -; MSSA: [[META15]] = !{!"int", [[META16:![0-9]+]], i64 0} -; MSSA: [[META16]] = !{!"char", [[META3]], i64 0} -; MSSA: [[INT_TBAA17]] = !{[[META18:![0-9]+]], [[META15]], i64 0} -; MSSA: [[META18]] = !{!"struct Y", [[META14]], i64 0} +; MSSA: [[INT_TBAA10]] = !{[[META11:![0-9]+]], [[META12:![0-9]+]], i64 0} +; MSSA: [[META11]] = !{!"struct X", [[META12]], i64 0} +; MSSA: [[META12]] = !{!"int", [[META13:![0-9]+]], i64 0} +; MSSA: [[META13]] = !{!"char", [[META3]], i64 0} +; MSSA: [[INT_TBAA14]] = !{[[META15:![0-9]+]], [[META12]], i64 0} +; MSSA: [[META15]] = !{!"struct Y", [[META11]], i64 0} ;. -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK: {{.*}} diff --git a/llvm/test/Transforms/GVN/vscale.ll b/llvm/test/Transforms/GVN/vscale.ll index b358df54750d8..d1628d79faa4a 100644 --- a/llvm/test/Transforms/GVN/vscale.ll +++ b/llvm/test/Transforms/GVN/vscale.ll @@ -5,18 +5,11 @@ ; Analyze Load from clobbering Load. define @load_store_clobber_load(ptr %p) { -; MDEP-LABEL: @load_store_clobber_load( -; MDEP-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 -; MDEP-NEXT: store zeroinitializer, ptr undef, align 16 -; MDEP-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD1]] -; MDEP-NEXT: ret [[ADD]] -; -; MSSA-LABEL: @load_store_clobber_load( -; MSSA-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 -; MSSA-NEXT: store zeroinitializer, ptr undef, align 16 -; MSSA-NEXT: [[LOAD2:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD2]] -; MSSA-NEXT: ret [[ADD]] +; CHECK-LABEL: @load_store_clobber_load( +; CHECK-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 +; CHECK-NEXT: store zeroinitializer, ptr undef, align 16 +; CHECK-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD1]] +; CHECK-NEXT: ret [[ADD]] ; %load1 = load , ptr %p store zeroinitializer, ptr undef @@ -41,18 +34,11 @@ define @load_store_clobber_load_mayalias(ptr %p, ptr %p2) { } define @load_store_clobber_load_noalias(ptr noalias %p, ptr noalias %p2) { -; MDEP-LABEL: @load_store_clobber_load_noalias( -; MDEP-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 -; MDEP-NEXT: store zeroinitializer, ptr [[P2:%.*]], align 16 -; MDEP-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD1]] -; MDEP-NEXT: ret [[ADD]] -; -; MSSA-LABEL: @load_store_clobber_load_noalias( -; MSSA-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 -; MSSA-NEXT: store zeroinitializer, ptr [[P2:%.*]], align 16 -; MSSA-NEXT: [[LOAD2:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD2]] -; MSSA-NEXT: ret [[ADD]] +; CHECK-LABEL: @load_store_clobber_load_noalias( +; CHECK-NEXT: [[LOAD1:%.*]] = load , ptr [[P:%.*]], align 16 +; CHECK-NEXT: store zeroinitializer, ptr [[P2:%.*]], align 16 +; CHECK-NEXT: [[ADD:%.*]] = add [[LOAD1]], [[LOAD1]] +; CHECK-NEXT: ret [[ADD]] ; %load1 = load , ptr %p store zeroinitializer, ptr %p2 @@ -63,18 +49,11 @@ define @load_store_clobber_load_noalias(ptr noalias %p, ptr n ; BasicAA return MayAlias for %gep1,%gep2, could improve as MustAlias. define i32 @load_clobber_load_gep1(ptr %p) { -; MDEP-LABEL: @load_clobber_load_gep1( -; MDEP-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 -; MDEP-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4 -; MDEP-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD1]] -; MDEP-NEXT: ret i32 [[ADD]] -; -; MSSA-LABEL: @load_clobber_load_gep1( -; MSSA-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 -; MSSA-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4 -; MSSA-NEXT: [[LOAD2:%.*]] = load i32, ptr [[GEP1]], align 4 -; MSSA-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]] -; MSSA-NEXT: ret i32 [[ADD]] +; CHECK-LABEL: @load_clobber_load_gep1( +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP1]], align 4 +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD1]] +; CHECK-NEXT: ret i32 [[ADD]] ; %gep1 = getelementptr , ptr %p, i64 0, i64 1 %load1 = load i32, ptr %gep1 @@ -154,14 +133,9 @@ define @load_clobber_load_sideeffect(ptr %p) { ; Analyze Load from clobbering Store. define @store_forward_to_load(ptr %p) { -; MDEP-LABEL: @store_forward_to_load( -; MDEP-NEXT: store zeroinitializer, ptr [[P:%.*]], align 16 -; MDEP-NEXT: ret zeroinitializer -; -; MSSA-LABEL: @store_forward_to_load( -; MSSA-NEXT: store zeroinitializer, ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @store_forward_to_load( +; CHECK-NEXT: store zeroinitializer, ptr [[P:%.*]], align 16 +; CHECK-NEXT: ret zeroinitializer ; store zeroinitializer, ptr %p %load = load , ptr %p @@ -201,15 +175,9 @@ define i32 @store_clobber_load() { declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) define i32 @memset_clobber_load(ptr %p) { -; MDEP-LABEL: @memset_clobber_load( -; MDEP-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false) -; MDEP-NEXT: ret i32 16843009 -; -; MSSA-LABEL: @memset_clobber_load( -; MSSA-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false) -; MSSA-NEXT: [[GEP:%.*]] = getelementptr , ptr [[P]], i64 0, i64 5 -; MSSA-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4 -; MSSA-NEXT: ret i32 [[LOAD]] +; CHECK-LABEL: @memset_clobber_load( +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 1, i64 200, i1 false) +; CHECK-NEXT: ret i32 16843009 ; tail call void @llvm.memset.p0.i64(ptr %p, i8 1, i64 200, i1 false) %gep = getelementptr , ptr %p, i64 0, i64 5 @@ -247,28 +215,15 @@ define i32 @memset_clobber_load_nonconst_index(ptr %p, i64 %idx1, i64 %idx2) { ; Load elimination across BBs define ptr @load_from_alloc_replaced_with_undef() { -; MDEP-LABEL: @load_from_alloc_replaced_with_undef( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[A:%.*]] = alloca , align 16 -; MDEP-NEXT: br i1 undef, label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: store zeroinitializer, ptr [[A]], align 16 -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: ret ptr [[A]] -; -; MSSA-LABEL: @load_from_alloc_replaced_with_undef( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[A:%.*]] = alloca , align 16 -; MSSA-NEXT: [[GEP:%.*]] = getelementptr , ptr [[A]], i64 0, i64 1 -; MSSA-NEXT: [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4 -; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[LOAD]], 0 -; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: store zeroinitializer, ptr [[A]], align 16 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: ret ptr [[A]] +; CHECK-LABEL: @load_from_alloc_replaced_with_undef( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A:%.*]] = alloca , align 16 +; CHECK-NEXT: br i1 undef, label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store zeroinitializer, ptr [[A]], align 16 +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: ret ptr [[A]] ; entry: %a = alloca @@ -286,29 +241,16 @@ if.end: } define i32 @redundant_load_elimination_1(ptr %p) { -; MDEP-LABEL: @redundant_load_elimination_1( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[GEP:%.*]] = getelementptr , ptr [[P:%.*]], i64 1, i64 1 -; MDEP-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4 -; MDEP-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0 -; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; MDEP: if.then: -; MDEP-NEXT: br label [[IF_END]] -; MDEP: if.end: -; MDEP-NEXT: ret i32 [[LOAD1]] -; -; MSSA-LABEL: @redundant_load_elimination_1( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[GEP:%.*]] = getelementptr , ptr [[P:%.*]], i64 1, i64 1 -; MSSA-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4 -; MSSA-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0 -; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[LOAD2:%.*]] = load i32, ptr [[GEP]], align 4 -; MSSA-NEXT: br label [[IF_END]] -; MSSA: if.end: -; MSSA-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOAD2]], [[IF_THEN]] ], [ [[LOAD1]], [[ENTRY:%.*]] ] -; MSSA-NEXT: ret i32 [[RESULT]] +; CHECK-LABEL: @redundant_load_elimination_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[GEP:%.*]] = getelementptr , ptr [[P:%.*]], i64 1, i64 1 +; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[GEP]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LOAD1]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: ret i32 [[LOAD1]] ; entry: %gep = getelementptr , ptr %p, i64 1, i64 1 @@ -359,30 +301,17 @@ if.else: } define void @redundant_load_elimination_zero_index(i1 %c, ptr %p, ptr %q) { -; MDEP-LABEL: @redundant_load_elimination_zero_index( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 -; MDEP-NEXT: store i32 0, ptr [[GEP1]], align 4 -; MDEP-NEXT: store i32 1, ptr [[P]], align 4 -; MDEP-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: store i32 0, ptr [[Q:%.*]], align 4 -; MDEP-NEXT: ret void -; MDEP: if.else: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @redundant_load_elimination_zero_index( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 -; MSSA-NEXT: store i32 0, ptr [[GEP1]], align 4 -; MSSA-NEXT: store i32 1, ptr [[P]], align 4 -; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[T:%.*]] = load i32, ptr [[GEP1]], align 4 -; MSSA-NEXT: store i32 [[T]], ptr [[Q:%.*]], align 4 -; MSSA-NEXT: ret void -; MSSA: if.else: -; MSSA-NEXT: ret void +; CHECK-LABEL: @redundant_load_elimination_zero_index( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 1 +; CHECK-NEXT: store i32 0, ptr [[GEP1]], align 4 +; CHECK-NEXT: store i32 1, ptr [[P]], align 4 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4 +; CHECK-NEXT: ret void +; CHECK: if.else: +; CHECK-NEXT: ret void ; entry: %gep1 = getelementptr , ptr %p, i64 0, i64 1 @@ -400,34 +329,19 @@ if.else: } define void @redundant_load_elimination_zero_index_1(i1 %c, ptr %p, ptr %q, i64 %i) { -; MDEP-LABEL: @redundant_load_elimination_zero_index_1( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1 -; MDEP-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 [[J]] -; MDEP-NEXT: store i32 0, ptr [[GEP1]], align 4 -; MDEP-NEXT: [[GEP2:%.*]] = getelementptr , ptr [[P]], i64 0, i64 [[I]] -; MDEP-NEXT: store i32 1, ptr [[GEP2]], align 4 -; MDEP-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] -; MDEP: if.then: -; MDEP-NEXT: store i32 0, ptr [[Q:%.*]], align 4 -; MDEP-NEXT: ret void -; MDEP: if.else: -; MDEP-NEXT: ret void -; -; MSSA-LABEL: @redundant_load_elimination_zero_index_1( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1 -; MSSA-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 [[J]] -; MSSA-NEXT: store i32 0, ptr [[GEP1]], align 4 -; MSSA-NEXT: [[GEP2:%.*]] = getelementptr , ptr [[P]], i64 0, i64 [[I]] -; MSSA-NEXT: store i32 1, ptr [[GEP2]], align 4 -; MSSA-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] -; MSSA: if.then: -; MSSA-NEXT: [[T:%.*]] = load i32, ptr [[GEP1]], align 4 -; MSSA-NEXT: store i32 [[T]], ptr [[Q:%.*]], align 4 -; MSSA-NEXT: ret void -; MSSA: if.else: -; MSSA-NEXT: ret void +; CHECK-LABEL: @redundant_load_elimination_zero_index_1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[J:%.*]] = add i64 [[I:%.*]], 1 +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr , ptr [[P:%.*]], i64 0, i64 [[J]] +; CHECK-NEXT: store i32 0, ptr [[GEP1]], align 4 +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr , ptr [[P]], i64 0, i64 [[I]] +; CHECK-NEXT: store i32 1, ptr [[GEP2]], align 4 +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4 +; CHECK-NEXT: ret void +; CHECK: if.else: +; CHECK-NEXT: ret void ; entry: %j = add i64 %i, 1 @@ -478,15 +392,10 @@ if.else: ; Different sizes / types define @load_v16i8_store_v4i32_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v16i8_store_v4i32_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast [[X]] to -; MDEP-NEXT: ret [[TMP1]] -; -; MSSA-LABEL: @load_v16i8_store_v4i32_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v16i8_store_v4i32_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[X]] to +; CHECK-NEXT: ret [[TMP1]] ; store %x, ptr %p %load = load , ptr %p @@ -494,15 +403,10 @@ define @load_v16i8_store_v4i32_forward_load(ptr %p, @load_v4f32_store_v4i32_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v4f32_store_v4i32_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast [[X]] to -; MDEP-NEXT: ret [[TMP1]] -; -; MSSA-LABEL: @load_v4f32_store_v4i32_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v4f32_store_v4i32_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[X]] to +; CHECK-NEXT: ret [[TMP1]] ; store %x, ptr %p %load = load , ptr %p @@ -510,15 +414,10 @@ define @load_v4f32_store_v4i32_forward_load(ptr %p, @load_v4f32_store_v16i8_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v4f32_store_v16i8_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast [[X]] to -; MDEP-NEXT: ret [[TMP1]] -; -; MSSA-LABEL: @load_v4f32_store_v16i8_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v4f32_store_v16i8_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[X]] to +; CHECK-NEXT: ret [[TMP1]] ; store %x, ptr %p %load = load , ptr %p @@ -526,15 +425,10 @@ define @load_v4f32_store_v16i8_forward_load(ptr %p, @load_v4i32_store_v4f32_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v4i32_store_v4f32_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast [[X]] to -; MDEP-NEXT: ret [[TMP1]] -; -; MSSA-LABEL: @load_v4i32_store_v4f32_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v4i32_store_v4f32_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[X]] to +; CHECK-NEXT: ret [[TMP1]] ; store %x, ptr %p %load = load , ptr %p @@ -601,16 +495,11 @@ define @load_v2i32_store_v4i32_forward_load_offsetc(ptr %p, < } define @load_v2p0_store_v4i32_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v2p0_store_v4i32_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = bitcast [[X]] to -; MDEP-NEXT: [[TMP2:%.*]] = inttoptr [[TMP1]] to -; MDEP-NEXT: ret [[TMP2]] -; -; MSSA-LABEL: @load_v2p0_store_v4i32_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v2p0_store_v4i32_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[X]] to +; CHECK-NEXT: [[TMP2:%.*]] = inttoptr [[TMP1]] to +; CHECK-NEXT: ret [[TMP2]] ; store %x, ptr %p %load = load , ptr %p @@ -618,15 +507,10 @@ define @load_v2p0_store_v4i32_forward_load(ptr %p, @load_v2i64_store_v2p0_forward_load(ptr %p, %x) { -; MDEP-LABEL: @load_v2i64_store_v2p0_forward_load( -; MDEP-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MDEP-NEXT: [[TMP1:%.*]] = ptrtoint [[X]] to -; MDEP-NEXT: ret [[TMP1]] -; -; MSSA-LABEL: @load_v2i64_store_v2p0_forward_load( -; MSSA-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v2i64_store_v2p0_forward_load( +; CHECK-NEXT: store [[X:%.*]], ptr [[P:%.*]], align 16 +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint [[X]] to +; CHECK-NEXT: ret [[TMP1]] ; store %x, ptr %p %load = load , ptr %p @@ -656,14 +540,9 @@ define <16 x i8> @load_v16i8_store_nxv4i32_forward_load(ptr %p, @load_v16i8_store_v4i32_forward_constant(ptr %p) { -; MDEP-LABEL: @load_v16i8_store_v4i32_forward_constant( -; MDEP-NEXT: store splat (i32 4), ptr [[P:%.*]], align 16 -; MDEP-NEXT: ret bitcast ( splat (i32 4) to ) -; -; MSSA-LABEL: @load_v16i8_store_v4i32_forward_constant( -; MSSA-NEXT: store splat (i32 4), ptr [[P:%.*]], align 16 -; MSSA-NEXT: [[LOAD:%.*]] = load , ptr [[P]], align 16 -; MSSA-NEXT: ret [[LOAD]] +; CHECK-LABEL: @load_v16i8_store_v4i32_forward_constant( +; CHECK-NEXT: store splat (i32 4), ptr [[P:%.*]], align 16 +; CHECK-NEXT: ret bitcast ( splat (i32 4) to ) ; store splat (i32 4), ptr %p %load = load , ptr %p @@ -693,65 +572,35 @@ define {} @load_v16i8_store_v4i32_struct_forward_load(ptr %p, } define { , , , } @bigexample({ , , , } %a) vscale_range(1,16) { -; MDEP-LABEL: @bigexample( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[REF_TMP:%.*]] = alloca { , , , }, align 16 -; MDEP-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull [[REF_TMP]]) -; MDEP-NEXT: [[A_ELT:%.*]] = extractvalue { , , , } [[A:%.*]], 0 -; MDEP-NEXT: store [[A_ELT]], ptr [[REF_TMP]], align 16 -; MDEP-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() -; MDEP-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 -; MDEP-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]] -; MDEP-NEXT: [[A_ELT2:%.*]] = extractvalue { , , , } [[A]], 1 -; MDEP-NEXT: store [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16 -; MDEP-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0]], 5 -; MDEP-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP2]] -; MDEP-NEXT: [[A_ELT4:%.*]] = extractvalue { , , , } [[A]], 2 -; MDEP-NEXT: store [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16 -; MDEP-NEXT: [[TMP3:%.*]] = mul i64 [[TMP0]], 48 -; MDEP-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]] -; MDEP-NEXT: [[A_ELT6:%.*]] = extractvalue { , , , } [[A]], 3 -; MDEP-NEXT: store [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16 -; MDEP-NEXT: [[TMP4:%.*]] = bitcast [[A_ELT]] to -; MDEP-NEXT: [[TMP5:%.*]] = insertvalue { , , , } poison, [[TMP4]], 0 -; MDEP-NEXT: [[TMP6:%.*]] = bitcast [[A_ELT2]] to -; MDEP-NEXT: [[TMP7:%.*]] = insertvalue { , , , } [[TMP5]], [[TMP6]], 1 -; MDEP-NEXT: [[TMP8:%.*]] = bitcast [[A_ELT4]] to -; MDEP-NEXT: [[TMP9:%.*]] = insertvalue { , , , } [[TMP7]], [[TMP8]], 2 -; MDEP-NEXT: [[TMP10:%.*]] = bitcast [[A_ELT6]] to -; MDEP-NEXT: [[TMP11:%.*]] = insertvalue { , , , } [[TMP9]], [[TMP10]], 3 -; MDEP-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull [[REF_TMP]]) -; MDEP-NEXT: ret { , , , } [[TMP11]] -; -; MSSA-LABEL: @bigexample( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[REF_TMP:%.*]] = alloca { , , , }, align 16 -; MSSA-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull [[REF_TMP]]) -; MSSA-NEXT: [[A_ELT:%.*]] = extractvalue { , , , } [[A:%.*]], 0 -; MSSA-NEXT: store [[A_ELT]], ptr [[REF_TMP]], align 16 -; MSSA-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() -; MSSA-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 -; MSSA-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]] -; MSSA-NEXT: [[A_ELT2:%.*]] = extractvalue { , , , } [[A]], 1 -; MSSA-NEXT: store [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16 -; MSSA-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0]], 5 -; MSSA-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP2]] -; MSSA-NEXT: [[A_ELT4:%.*]] = extractvalue { , , , } [[A]], 2 -; MSSA-NEXT: store [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16 -; MSSA-NEXT: [[TMP3:%.*]] = mul i64 [[TMP0]], 48 -; MSSA-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]] -; MSSA-NEXT: [[A_ELT6:%.*]] = extractvalue { , , , } [[A]], 3 -; MSSA-NEXT: store [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16 -; MSSA-NEXT: [[DOTUNPACK:%.*]] = load , ptr [[REF_TMP]], align 16 -; MSSA-NEXT: [[TMP4:%.*]] = insertvalue { , , , } poison, [[DOTUNPACK]], 0 -; MSSA-NEXT: [[DOTUNPACK8:%.*]] = load , ptr [[REF_TMP_REPACK1]], align 16 -; MSSA-NEXT: [[TMP5:%.*]] = insertvalue { , , , } [[TMP4]], [[DOTUNPACK8]], 1 -; MSSA-NEXT: [[DOTUNPACK10:%.*]] = load , ptr [[REF_TMP_REPACK3]], align 16 -; MSSA-NEXT: [[TMP6:%.*]] = insertvalue { , , , } [[TMP5]], [[DOTUNPACK10]], 2 -; MSSA-NEXT: [[DOTUNPACK12:%.*]] = load , ptr [[REF_TMP_REPACK5]], align 16 -; MSSA-NEXT: [[TMP7:%.*]] = insertvalue { , , , } [[TMP6]], [[DOTUNPACK12]], 3 -; MSSA-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull [[REF_TMP]]) -; MSSA-NEXT: ret { , , , } [[TMP7]] +; CHECK-LABEL: @bigexample( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[REF_TMP:%.*]] = alloca { , , , }, align 16 +; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr nonnull [[REF_TMP]]) +; CHECK-NEXT: [[A_ELT:%.*]] = extractvalue { , , , } [[A:%.*]], 0 +; CHECK-NEXT: store [[A_ELT]], ptr [[REF_TMP]], align 16 +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 4 +; CHECK-NEXT: [[REF_TMP_REPACK1:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP1]] +; CHECK-NEXT: [[A_ELT2:%.*]] = extractvalue { , , , } [[A]], 1 +; CHECK-NEXT: store [[A_ELT2]], ptr [[REF_TMP_REPACK1]], align 16 +; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP0]], 5 +; CHECK-NEXT: [[REF_TMP_REPACK3:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP2]] +; CHECK-NEXT: [[A_ELT4:%.*]] = extractvalue { , , , } [[A]], 2 +; CHECK-NEXT: store [[A_ELT4]], ptr [[REF_TMP_REPACK3]], align 16 +; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP0]], 48 +; CHECK-NEXT: [[REF_TMP_REPACK5:%.*]] = getelementptr inbounds i8, ptr [[REF_TMP]], i64 [[TMP3]] +; CHECK-NEXT: [[A_ELT6:%.*]] = extractvalue { , , , } [[A]], 3 +; CHECK-NEXT: store [[A_ELT6]], ptr [[REF_TMP_REPACK5]], align 16 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast [[A_ELT]] to +; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { , , , } poison, [[TMP4]], 0 +; CHECK-NEXT: [[TMP6:%.*]] = bitcast [[A_ELT2]] to +; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { , , , } [[TMP5]], [[TMP6]], 1 +; CHECK-NEXT: [[TMP8:%.*]] = bitcast [[A_ELT4]] to +; CHECK-NEXT: [[TMP9:%.*]] = insertvalue { , , , } [[TMP7]], [[TMP8]], 2 +; CHECK-NEXT: [[TMP10:%.*]] = bitcast [[A_ELT6]] to +; CHECK-NEXT: [[TMP11:%.*]] = insertvalue { , , , } [[TMP9]], [[TMP10]], 3 +; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr nonnull [[REF_TMP]]) +; CHECK-NEXT: ret { , , , } [[TMP11]] ; entry: %ref.tmp = alloca { , , , }, align 16 @@ -795,21 +644,12 @@ entry: } define @scalable_store_to_fixed_load( %.coerce) vscale_range(4,4) { -; MDEP-LABEL: @scalable_store_to_fixed_load( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64 -; MDEP-NEXT: [[TMP0:%.*]] = fadd [[DOTCOERCE:%.*]], [[DOTCOERCE]] -; MDEP-NEXT: store [[TMP0]], ptr [[RETVAL]], align 16 -; MDEP-NEXT: ret [[TMP0]] -; -; MSSA-LABEL: @scalable_store_to_fixed_load( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64 -; MSSA-NEXT: [[TMP0:%.*]] = fadd [[DOTCOERCE:%.*]], [[DOTCOERCE]] -; MSSA-NEXT: store [[TMP0]], ptr [[RETVAL]], align 16 -; MSSA-NEXT: [[TMP1:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64 -; MSSA-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv4f32.v16f32( poison, <16 x float> [[TMP1]], i64 0) -; MSSA-NEXT: ret [[CAST_SCALABLE]] +; CHECK-LABEL: @scalable_store_to_fixed_load( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RETVAL:%.*]] = alloca { <16 x float> }, align 64 +; CHECK-NEXT: [[TMP0:%.*]] = fadd [[DOTCOERCE:%.*]], [[DOTCOERCE]] +; CHECK-NEXT: store [[TMP0]], ptr [[RETVAL]], align 16 +; CHECK-NEXT: ret [[TMP0]] ; entry: %retval = alloca { <16 x float> } @@ -822,19 +662,11 @@ entry: ; Here, only the lower bound for the vscale is known, but this is enough to allow a forward to a load to 16 elements. define @scalable_store_to_fixed_load_only_lower_bound( %a) vscale_range(4) { -; MDEP-LABEL: @scalable_store_to_fixed_load_only_lower_bound( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[RETVAL:%.*]] = alloca { }, align 16 -; MDEP-NEXT: store [[A:%.*]], ptr [[RETVAL]], align 16 -; MDEP-NEXT: ret [[A]] -; -; MSSA-LABEL: @scalable_store_to_fixed_load_only_lower_bound( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[RETVAL:%.*]] = alloca { }, align 16 -; MSSA-NEXT: store [[A:%.*]], ptr [[RETVAL]], align 16 -; MSSA-NEXT: [[TMP0:%.*]] = load <16 x float>, ptr [[RETVAL]], align 64 -; MSSA-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv4f32.v16f32( poison, <16 x float> [[TMP0]], i64 0) -; MSSA-NEXT: ret [[CAST_SCALABLE]] +; CHECK-LABEL: @scalable_store_to_fixed_load_only_lower_bound( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RETVAL:%.*]] = alloca { }, align 16 +; CHECK-NEXT: store [[A:%.*]], ptr [[RETVAL]], align 16 +; CHECK-NEXT: ret [[A]] ; entry: %retval = alloca { } @@ -921,19 +753,12 @@ entry: ; This function does not have a fixed vscale, but the loaded vector is still known ; to be smaller or equal in size compared to the stored vector. define <4 x float> @scalable_store_to_small_fixed_load( %a) { -; MDEP-LABEL: @scalable_store_to_small_fixed_load( -; MDEP-NEXT: entry: -; MDEP-NEXT: [[PTR:%.*]] = alloca , align 16 -; MDEP-NEXT: store [[A:%.*]], ptr [[PTR]], align 16 -; MDEP-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.vector.extract.v4f32.nxv4f32( [[A]], i64 0) -; MDEP-NEXT: ret <4 x float> [[TMP0]] -; -; MSSA-LABEL: @scalable_store_to_small_fixed_load( -; MSSA-NEXT: entry: -; MSSA-NEXT: [[PTR:%.*]] = alloca , align 16 -; MSSA-NEXT: store [[A:%.*]], ptr [[PTR]], align 16 -; MSSA-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[PTR]], align 16 -; MSSA-NEXT: ret <4 x float> [[TMP0]] +; CHECK-LABEL: @scalable_store_to_small_fixed_load( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[PTR:%.*]] = alloca , align 16 +; CHECK-NEXT: store [[A:%.*]], ptr [[PTR]], align 16 +; CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.vector.extract.v4f32.nxv4f32( [[A]], i64 0) +; CHECK-NEXT: ret <4 x float> [[TMP0]] ; entry: %ptr = alloca @@ -941,3 +766,6 @@ entry: %1 = load <4 x float>, ptr %ptr ret <4 x float> %1 } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MDEP: {{.*}} +; MSSA: {{.*}}