Index: include/llvm/Analysis/AliasSetTracker.h =================================================================== --- include/llvm/Analysis/AliasSetTracker.h +++ include/llvm/Analysis/AliasSetTracker.h @@ -30,6 +30,7 @@ class LoadInst; class StoreInst; class VAArgInst; +class MemSetInst; class AliasSetTracker; class AliasSet; @@ -329,6 +330,7 @@ bool add(LoadInst *LI); bool add(StoreInst *SI); bool add(VAArgInst *VAAI); + bool add(MemSetInst *MSI); bool add(Instruction *I); // Dispatch to one of the other add methods... void add(BasicBlock &BB); // Add all instructions in basic block void add(const AliasSetTracker &AST); // Add alias relations from another AST @@ -341,6 +343,7 @@ bool remove(LoadInst *LI); bool remove(StoreInst *SI); bool remove(VAArgInst *VAAI); + bool remove(MemSetInst *MSI); bool remove(Instruction *I); void remove(AliasSet &AS); bool removeUnknown(Instruction *I); Index: lib/Analysis/AliasSetTracker.cpp =================================================================== --- lib/Analysis/AliasSetTracker.cpp +++ lib/Analysis/AliasSetTracker.cpp @@ -342,6 +342,24 @@ return NewPtr; } +bool AliasSetTracker::add(MemSetInst *MSI) { + AAMDNodes AAInfo; + MSI->getAAMetadata(AAInfo); + + bool NewPtr; + uint64_t Len; + + if (ConstantInt *C = dyn_cast(MSI->getLength())) + Len = C->getZExtValue(); + else + Len = MemoryLocation::UnknownSize; + + AliasSet &AS = + addPointer(MSI->getDest(), Len, AAInfo, AliasSet::ModAccess, NewPtr); + if (MSI->isVolatile()) + AS.setVolatile(); + return NewPtr; +} bool AliasSetTracker::addUnknown(Instruction *Inst) { if (isa(Inst)) @@ -368,7 +386,10 @@ return add(SI); if (VAArgInst *VAAI = dyn_cast(I)) return add(VAAI); + if (MemSetInst *MSI = dyn_cast(I)) + return add(MSI); return addUnknown(I); + // FIXME: add support of memcpy and memmove. } void AliasSetTracker::add(BasicBlock &BB) { @@ -479,6 +500,23 @@ return true; } +bool AliasSetTracker::remove(MemSetInst *MSI) { + AAMDNodes AAInfo; + MSI->getAAMetadata(AAInfo); + uint64_t Len; + + if (ConstantInt *C = dyn_cast(MSI->getLength())) + Len = C->getZExtValue(); + else + Len = MemoryLocation::UnknownSize; + + AliasSet *AS = findAliasSetForPointer(MSI->getDest(), Len, AAInfo); + if (!AS) + return false; + remove(*AS); + return true; +} + bool AliasSetTracker::removeUnknown(Instruction *I) { if (!I->mayReadOrWriteMemory()) return false; // doesn't alias anything @@ -497,7 +535,10 @@ return remove(SI); if (VAArgInst *VAAI = dyn_cast(I)) return remove(VAAI); + if (MemSetInst *MSI = dyn_cast(I)) + return remove(MSI); return removeUnknown(I); + // FIXME: add support of memcpy and memmove. } Index: test/Transforms/LICM/AliasSetMemSet.ll =================================================================== --- /dev/null +++ test/Transforms/LICM/AliasSetMemSet.ll @@ -0,0 +1,51 @@ +; RUN: opt < %s -loop-deletion -licm -loop-idiom -disable-output +; Check no assertion when loop-idiom deletes the MemSet already analyzed by licm +define void @set_array() { + br i1 false, label %bb3.preheader.lr.ph, label %bb9 + +bb3.preheader.lr.ph: ; preds = %0 + br label %bb3.preheader + +bb4: ; preds = %bb4.lr.ph, %bb7 + %j.3.06 = phi i8 [ %j.3.17, %bb4.lr.ph ], [ %_tmp13, %bb7 ] + br label %bb6 + +bb6: ; preds = %bb4, %bb6 + %k.4.04 = phi i8 [ 0, %bb4 ], [ %_tmp9, %bb6 ] + %_tmp31 = sext i8 %j.3.06 to i64 + %_tmp4 = mul i64 %_tmp31, 10 + %_tmp5 = getelementptr i8, i8* undef, i64 %_tmp4 + %_tmp7 = getelementptr i8, i8* %_tmp5, i8 %k.4.04 + store i8 42, i8* %_tmp7 + %_tmp9 = add i8 %k.4.04, 1 + %_tmp11 = icmp slt i8 %_tmp9, 10 + br i1 %_tmp11, label %bb6, label %bb7 + +bb7: ; preds = %bb6 + %_tmp13 = add i8 %j.3.06, 1 + %_tmp15 = icmp slt i8 %_tmp13, 2 + br i1 %_tmp15, label %bb4, label %bb3.bb1.loopexit_crit_edge + +bb3.bb1.loopexit_crit_edge: ; preds = %bb7 + %split = phi i8 [ %_tmp13, %bb7 ] + br label %bb1.loopexit + +bb1.loopexit: ; preds = %bb3.bb1.loopexit_crit_edge, %bb3.preheader + %j.3.0.lcssa = phi i8 [ %split, %bb3.bb1.loopexit_crit_edge ], [ %j.3.17, %bb3.preheader ] + br i1 false, label %bb3.preheader, label %bb1.bb9_crit_edge + +bb3.preheader: ; preds = %bb3.preheader.lr.ph, %bb1.loopexit + %j.3.17 = phi i8 [ undef, %bb3.preheader.lr.ph ], [ %j.3.0.lcssa, %bb1.loopexit ] + %_tmp155 = icmp slt i8 %j.3.17, 2 + br i1 %_tmp155, label %bb4.lr.ph, label %bb1.loopexit + +bb4.lr.ph: ; preds = %bb3.preheader + br label %bb4 + +bb1.bb9_crit_edge: ; preds = %bb1.loopexit + br label %bb9 + +bb9: ; preds = %bb1.bb9_crit_edge, %0 + ret void +} +