<p dir="ltr">Seems it was the cause; <br>
<a href="http://bb.pgr.jp/builders/clang-3stage-x86_64-linux/builds/8890">http://bb.pgr.jp/builders/clang-3stage-x86_64-linux/builds/8890</a></p>
<p dir="ltr">Thanks!</p>
<br><div class="gmail_quote"><div dir="ltr">2015年10月28日(水) 15:18 Hal Finkel via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">----- Original Message -----<br>
> From: "Juergen Ributzka" <<a href="mailto:juergen@apple.com" target="_blank">juergen@apple.com</a>><br>
> To: "Hal Finkel" <<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>><br>
> Cc: <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> Sent: Wednesday, October 28, 2015 4:56:59 PM<br>
> Subject: Re: [llvm] r251451 - [AliasSetTracker] Use mod/ref information for UnknownInstr<br>
><br>
> Hi Hal,<br>
><br>
><br>
> looks like this change broke the stage2 compiler:<br>
> <a href="http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto/6989/" rel="noreferrer" target="_blank">http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto/6989/</a><br>
><br>
><br>
> Could you please revert the patch?<br>
><br>
<br>
Reverted in r251562.<br>
<br>
 -Hal<br>
<br>
><br>
> Thanks<br>
><br>
><br>
> Cheers,<br>
> Juergen<br>
><br>
><br>
><br>
><br>
><br>
><br>
><br>
> On Oct 27, 2015, at 1:37 PM, Hal Finkel via llvm-commits <<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a> > wrote:<br>
><br>
><br>
> Author: hfinkel<br>
> Date: Tue Oct 27 15:37:04 2015<br>
> New Revision: 251451<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251451&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251451&view=rev</a><br>
> Log:<br>
> [AliasSetTracker] Use mod/ref information for UnknownInstr<br>
><br>
> AliasSetTracker does not need to convert the access mode to<br>
> ModRefAccess if the<br>
> new visited UnknownInst has only 'REF' modrefinfo to existing<br>
> pointers in the<br>
> sets.<br>
><br>
> Patch by Andrew Zhogin!<br>
><br>
> Added:<br>
> llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll<br>
> Modified:<br>
> llvm/trunk/include/llvm/Analysis/AliasSetTracker.h<br>
> llvm/trunk/lib/Analysis/AliasSetTracker.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/Analysis/AliasSetTracker.h<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasSetTracker.h?rev=251451&r1=251450&r2=251451&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasSetTracker.h?rev=251451&r1=251450&r2=251451&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Analysis/AliasSetTracker.h (original)<br>
> +++ llvm/trunk/include/llvm/Analysis/AliasSetTracker.h Tue Oct 27<br>
> 15:37:04 2015<br>
> @@ -124,12 +124,7 @@ class AliasSet : public ilist_node<Alias<br>
> /// memory (and not any particular access), whether it modifies or<br>
> references<br>
> /// the memory, or whether it does both. The lattice goes from<br>
> "NoAccess" to<br>
> /// either RefAccess or ModAccess, then to ModRefAccess as necessary.<br>
> - enum AccessLattice {<br>
> - NoAccess = 0,<br>
> - RefAccess = 1,<br>
> - ModAccess = 2,<br>
> - ModRefAccess = RefAccess | ModAccess<br>
> - };<br>
> + typedef ModRefInfo AccessLattice;<br>
> unsigned Access : 2;<br>
><br>
> /// The kind of alias relationship between pointers of the set.<br>
> @@ -160,8 +155,8 @@ class AliasSet : public ilist_node<Alias<br>
><br>
> public:<br>
> /// Accessors...<br>
> - bool isRef() const { return Access & RefAccess; }<br>
> - bool isMod() const { return Access & ModAccess; }<br>
> + bool isRef() const { return Access & MRI_Ref; }<br>
> + bool isMod() const { return Access & MRI_Mod; }<br>
> bool isMustAlias() const { return Alias == SetMustAlias; }<br>
> bool isMayAlias() const { return Alias == SetMayAlias; }<br>
><br>
> @@ -226,7 +221,7 @@ private:<br>
> friend struct ilist_sentinel_traits<AliasSet>;<br>
> AliasSet()<br>
> : PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr),<br>
> RefCount(0),<br>
> - Access(NoAccess), Alias(SetMustAlias), Volatile(false) {<br>
> + Access(MRI_NoModRef), Alias(SetMustAlias), Volatile(false) {<br>
> }<br>
><br>
> AliasSet(const AliasSet &AS) = delete;<br>
> @@ -254,9 +249,9 @@ private:<br>
> void removeFromTracker(AliasSetTracker &AST);<br>
><br>
> void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t<br>
> Size,<br>
> - const AAMDNodes &AAInfo,<br>
> + const AAMDNodes &AAInfo, ModRefInfo MR,<br>
> bool KnownMustAlias = false);<br>
> - void addUnknownInst(Instruction *I, AliasAnalysis &AA);<br>
> + void addUnknownInst(Instruction *I, AliasAnalysis &AA, ModRefInfo<br>
> MR);<br>
> void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {<br>
> bool WasEmpty = UnknownInsts.empty();<br>
> for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)<br>
> @@ -273,10 +268,18 @@ private:<br>
> public:<br>
> /// aliasesPointer - Return true if the specified pointer "may" (or<br>
> must)<br>
> /// alias one of the members in the set.<br>
> - ///<br>
> + /// MRcommon - if Ptr is aliased by existing UnknownInsts,<br>
> + /// then not-null MRcommon will be set to the worst ModRefInfo met<br>
> + ///<br>
> bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes<br>
> &AAInfo,<br>
> - AliasAnalysis &AA) const;<br>
> - bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA)<br>
> const;<br>
> + AliasAnalysis &AA, ModRefInfo* MRcommon = nullptr) const;<br>
> + /// aliasesUnknownInst - Return true if the specified UnknownInst<br>
> + /// has not-null ModRefInfo (not MRI_NoModRef) with some<br>
> + /// pointer or UnknownInst already existing in AliasSet<br>
> + /// MRcommon - not-null MRcommon will be set to the worst<br>
> ModRefInfo met<br>
> + ///<br>
> + bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA,<br>
> + ModRefInfo* MRcommon = nullptr) const;<br>
> };<br>
><br>
> inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {<br>
> @@ -434,9 +437,11 @@ private:<br>
> return AS;<br>
> }<br>
> AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,<br>
> - const AAMDNodes &AAInfo);<br>
> + const AAMDNodes &AAInfo,<br>
> + ModRefInfo* MRcommonPtr = nullptr);<br>
><br>
> - AliasSet *findAliasSetForUnknownInst(Instruction *Inst);<br>
> + AliasSet *findAliasSetForUnknownInst(Instruction *Inst,<br>
> + ModRefInfo* MRcommonPtr = nullptr);<br>
> };<br>
><br>
> inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker<br>
> &AST) {<br>
><br>
> Modified: llvm/trunk/lib/Analysis/AliasSetTracker.cpp<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=251451&r1=251450&r2=251451&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasSetTracker.cpp?rev=251451&r1=251450&r2=251451&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Analysis/AliasSetTracker.cpp (original)<br>
> +++ llvm/trunk/lib/Analysis/AliasSetTracker.cpp Tue Oct 27 15:37:04<br>
> 2015<br>
> @@ -95,7 +95,7 @@ void AliasSet::removeFromTracker(AliasSe<br>
><br>
> void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry,<br>
> uint64_t Size, const AAMDNodes &AAInfo,<br>
> - bool KnownMustAlias) {<br>
> + ModRefInfo MR, bool KnownMustAlias) {<br>
> assert(!Entry.hasAliasSet() && "Entry already in set!");<br>
><br>
> // Check to see if we have to downgrade to _may_ alias.<br>
> @@ -112,6 +112,9 @@ void AliasSet::addPointer(AliasSetTracke<br>
> assert(Result != NoAlias && "Cannot be part of must set!");<br>
> }<br>
><br>
> + // upgrading access if existing UnknownInst has ModRef with new<br>
> pointer<br>
> + Access |= MR;<br>
> +<br>
> Entry.setAliasSet(this);<br>
> Entry.updateSizeAndAAInfo(Size, AAInfo);<br>
><br>
> @@ -123,20 +126,34 @@ void AliasSet::addPointer(AliasSetTracke<br>
> addRef(); // Entry points to alias set.<br>
> }<br>
><br>
> -void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) {<br>
> +void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA,<br>
> + ModRefInfo MR) {<br>
> if (UnknownInsts.empty())<br>
> addRef();<br>
> UnknownInsts.emplace_back(I);<br>
><br>
> if (!I->mayWriteToMemory()) {<br>
> Alias = SetMayAlias;<br>
> - Access |= RefAccess;<br>
> + Access |= MRI_Ref;<br>
> return;<br>
> }<br>
><br>
> - // FIXME: This should use mod/ref information to make this not suck<br>
> so bad<br>
> Alias = SetMayAlias;<br>
> - Access = ModRefAccess;<br>
> + Access |= MR;<br>
> +}<br>
> +<br>
> +namespace {<br>
> + /// returns true if there is no request of worst ModRefInfo<br>
> + /// (MRcommonPtr is null)<br>
> + /// or when achieved maximum ModRefInfo (MRI_ModRef).<br>
> + bool processMR(ModRefInfo MR, ModRefInfo* MRcommonPtr, ModRefInfo&<br>
> MRcommon) {<br>
> + MRcommon = ModRefInfo(MRcommon | MR);<br>
> + return !MRcommonPtr || (MRcommon == MRI_ModRef);<br>
> + }<br>
> + bool fillExitMR(ModRefInfo* MRcommonPtr, ModRefInfo& MRcommon) {<br>
> + if (MRcommonPtr) *MRcommonPtr = MRcommon;<br>
> + return MRcommon != MRI_NoModRef;<br>
> + }<br>
> }<br>
><br>
> /// aliasesPointer - Return true if the specified pointer "may" (or<br>
> must)<br>
> @@ -144,7 +161,8 @@ void AliasSet::addUnknownInst(Instructio<br>
> ///<br>
> bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size,<br>
> const AAMDNodes &AAInfo,<br>
> - AliasAnalysis &AA) const {<br>
> + AliasAnalysis &AA,<br>
> + ModRefInfo* MRcommonPtr) const {<br>
> if (Alias == SetMustAlias) {<br>
> assert(UnknownInsts.empty() && "Illegal must alias set!");<br>
><br>
> @@ -164,35 +182,44 @@ bool AliasSet::aliasesPointer(const Valu<br>
> MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))<br>
> return true;<br>
><br>
> + // to gather worst ModRefInfo<br>
> + ModRefInfo MRcommon = MRI_NoModRef;<br>
> +<br>
> // Check the unknown instructions...<br>
> if (!UnknownInsts.empty()) {<br>
> for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i)<br>
> - if (AA.getModRefInfo(UnknownInsts[i],<br>
> - MemoryLocation(Ptr, Size, AAInfo)) != MRI_NoModRef)<br>
> - return true;<br>
> + if (processMR(AA.getModRefInfo(UnknownInsts[i],<br>
> + MemoryLocation(Ptr, Size, AAInfo)), MRcommonPtr, MRcommon))<br>
> + return fillExitMR(MRcommonPtr, MRcommon);<br>
> }<br>
><br>
> - return false;<br>
> + return fillExitMR(MRcommonPtr, MRcommon);<br>
> }<br>
><br>
> bool AliasSet::aliasesUnknownInst(const Instruction *Inst,<br>
> - AliasAnalysis &AA) const {<br>
> + AliasAnalysis &AA,<br>
> + ModRefInfo* MRcommonPtr) const {<br>
> if (!Inst->mayReadOrWriteMemory())<br>
> return false;<br>
><br>
> + // to gather worst ModRefInfo<br>
> + ModRefInfo MRcommon = MRI_NoModRef;<br>
> +<br>
> for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) {<br>
> ImmutableCallSite C1(getUnknownInst(i)), C2(Inst);<br>
> - if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef ||<br>
> - AA.getModRefInfo(C2, C1) != MRI_NoModRef)<br>
> - return true;<br>
> + if (!C1 || !C2 ||<br>
> + processMR(AA.getModRefInfo(C1, C2), MRcommonPtr, MRcommon) ||<br>
> + processMR(AA.getModRefInfo(C2, C1), MRcommonPtr, MRcommon))<br>
> + return fillExitMR(MRcommonPtr, MRcommon);<br>
> }<br>
><br>
> - for (iterator I = begin(), E = end(); I != E; ++I)<br>
> - if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(),<br>
> I.getSize(),<br>
> - I.getAAInfo())) != MRI_NoModRef)<br>
> - return true;<br>
> -<br>
> - return false;<br>
> + for (iterator I = begin(), E = end(); I != E; ++I) {<br>
> + ModRefInfo MR = AA.getModRefInfo(<br>
> + Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()));<br>
> + if (processMR(MR, MRcommonPtr, MRcommon))<br>
> + return fillExitMR(MRcommonPtr, MRcommon);<br>
> + }<br>
> + return fillExitMR(MRcommonPtr, MRcommon);<br>
> }<br>
><br>
> void AliasSetTracker::clear() {<br>
> @@ -214,11 +241,15 @@ void AliasSetTracker::clear() {<br>
> ///<br>
> AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,<br>
> uint64_t Size,<br>
> - const AAMDNodes &AAInfo) {<br>
> + const AAMDNodes &AAInfo,<br>
> + ModRefInfo* MRcommonPtr) {<br>
> AliasSet *FoundSet = nullptr;<br>
> for (iterator I = begin(), E = end(); I != E;) {<br>
> iterator Cur = I++;<br>
> - if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA))<br>
> continue;<br>
> + ModRefInfo MR = MRI_NoModRef;<br>
> + if (Cur->Forward || !Cur->aliasesPointer(Ptr, Size, AAInfo, AA,<br>
> &MR))<br>
> + continue;<br>
> + *MRcommonPtr = ModRefInfo(*MRcommonPtr | MR);<br>
><br>
> if (!FoundSet) { // If this is the first alias set ptr can go into.<br>
> FoundSet = &*Cur; // Remember it.<br>
> @@ -248,12 +279,15 @@ bool AliasSetTracker::containsUnknown(co<br>
> return false;<br>
> }<br>
><br>
> -AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction<br>
> *Inst) {<br>
> +AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction<br>
> *Inst,<br>
> + ModRefInfo* MRcommonPtr) {<br>
> AliasSet *FoundSet = nullptr;<br>
> for (iterator I = begin(), E = end(); I != E;) {<br>
> iterator Cur = I++;<br>
> - if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA))<br>
> + ModRefInfo MR = MRI_NoModRef;<br>
> + if (Cur->Forward || !Cur->aliasesUnknownInst(Inst, AA, &MR))<br>
> continue;<br>
> + *MRcommonPtr = ModRefInfo(*MRcommonPtr | MR);<br>
> if (!FoundSet) // If this is the first alias set ptr can go into.<br>
> FoundSet = &*Cur; // Remember it.<br>
> else if (!Cur->Forward) // Otherwise, we must merge the sets.<br>
> @@ -279,22 +313,23 @@ AliasSet &AliasSetTracker::getAliasSetFo<br>
> return *Entry.getAliasSet(*this)->getForwardedTarget(*this);<br>
> }<br>
><br>
> - if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo)) {<br>
> + ModRefInfo MR = MRI_NoModRef;<br>
> + if (AliasSet *AS = findAliasSetForPointer(Pointer, Size, AAInfo,<br>
> &MR)) {<br>
> // Add it to the alias set it aliases.<br>
> - AS->addPointer(*this, Entry, Size, AAInfo);<br>
> + AS->addPointer(*this, Entry, Size, AAInfo, MR);<br>
> return *AS;<br>
> }<br>
><br>
> if (New) *New = true;<br>
> // Otherwise create a new alias set to hold the loaded pointer.<br>
> AliasSets.push_back(new AliasSet());<br>
> - AliasSets.back().addPointer(*this, Entry, Size, AAInfo);<br>
> + AliasSets.back().addPointer(*this, Entry, Size, AAInfo,<br>
> MRI_NoModRef);<br>
> return AliasSets.back();<br>
> }<br>
><br>
> bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const AAMDNodes<br>
> &AAInfo) {<br>
> bool NewPtr;<br>
> - addPointer(Ptr, Size, AAInfo, AliasSet::NoAccess, NewPtr);<br>
> + addPointer(Ptr, Size, AAInfo, MRI_NoModRef, NewPtr);<br>
> return NewPtr;<br>
> }<br>
><br>
> @@ -305,7 +340,7 @@ bool AliasSetTracker::add(LoadInst *LI)<br>
> AAMDNodes AAInfo;<br>
> LI->getAAMetadata(AAInfo);<br>
><br>
> - AliasSet::AccessLattice Access = AliasSet::RefAccess;<br>
> + AliasSet::AccessLattice Access = MRI_Ref;<br>
> bool NewPtr;<br>
> const DataLayout &DL = LI->getModule()->getDataLayout();<br>
> AliasSet &AS = addPointer(LI->getOperand(0),<br>
> @@ -321,7 +356,7 @@ bool AliasSetTracker::add(StoreInst *SI)<br>
> AAMDNodes AAInfo;<br>
> SI->getAAMetadata(AAInfo);<br>
><br>
> - AliasSet::AccessLattice Access = AliasSet::ModAccess;<br>
> + AliasSet::AccessLattice Access = MRI_Mod;<br>
> bool NewPtr;<br>
> const DataLayout &DL = SI->getModule()->getDataLayout();<br>
> Value *Val = SI->getOperand(0);<br>
> @@ -338,7 +373,7 @@ bool AliasSetTracker::add(VAArgInst *VAA<br>
><br>
> bool NewPtr;<br>
> addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo,<br>
> - AliasSet::ModRefAccess, NewPtr);<br>
> + MRI_ModRef, NewPtr);<br>
> return NewPtr;<br>
> }<br>
><br>
> @@ -349,14 +384,15 @@ bool AliasSetTracker::addUnknown(Instruc<br>
> if (!Inst->mayReadOrWriteMemory())<br>
> return true; // doesn't alias anything<br>
><br>
> - AliasSet *AS = findAliasSetForUnknownInst(Inst);<br>
> + ModRefInfo MR = MRI_NoModRef;<br>
> + AliasSet *AS = findAliasSetForUnknownInst(Inst, &MR);<br>
> if (AS) {<br>
> - AS->addUnknownInst(Inst, AA);<br>
> + AS->addUnknownInst(Inst, AA, MR);<br>
> return false;<br>
> }<br>
> AliasSets.push_back(new AliasSet());<br>
> AS = &AliasSets.back();<br>
> - AS->addUnknownInst(Inst, AA);<br>
> + AS->addUnknownInst(Inst, AA, MR);<br>
> return true;<br>
> }<br>
><br>
> @@ -556,7 +592,7 @@ void AliasSetTracker::copyValue(Value *F<br>
> I = PointerMap.find_as(From);<br>
> AliasSet *AS = I->second->getAliasSet(*this);<br>
> AS->addPointer(*this, Entry, I->second->getSize(),<br>
> - I->second->getAAInfo(),<br>
> + I->second->getAAInfo(), MRI_NoModRef,<br>
> true);<br>
> }<br>
><br>
> @@ -570,10 +606,10 @@ void AliasSet::print(raw_ostream &OS) co<br>
> OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";<br>
> OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";<br>
> switch (Access) {<br>
> - case NoAccess: OS << "No access "; break;<br>
> - case RefAccess: OS << "Ref "; break;<br>
> - case ModAccess: OS << "Mod "; break;<br>
> - case ModRefAccess: OS << "Mod/Ref "; break;<br>
> + case MRI_NoModRef: OS << "No access "; break;<br>
> + case MRI_Ref: OS << "Ref "; break;<br>
> + case MRI_Mod: OS << "Mod "; break;<br>
> + case MRI_ModRef: OS << "Mod/Ref "; break;<br>
> default: llvm_unreachable("Bad value for Access!");<br>
> }<br>
> if (isVolatile()) OS << "[volatile] ";<br>
><br>
> Added: llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll?rev=251451&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll?rev=251451&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll<br>
> (added)<br>
> +++ llvm/trunk/test/Transforms/LICM/licm_call_referenced_ptr.ll Tue<br>
> Oct 27 15:37:04 2015<br>
> @@ -0,0 +1,40 @@<br>
> +; RUN: opt < %s -basicaa -licm -S | FileCheck %s<br>
> +<br>
> +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8*<br>
> nocapture, i64, i32, i1) nounwind<br>
> +<br>
> +define i8 @"main"() {<br>
> +entry:<br>
> + %A = alloca [64 x i8]<br>
> + %B = alloca [4 x i8]<br>
> + %A0 = getelementptr [64 x i8], [64 x i8]* %A, i32 0, i32 0<br>
> + %B0 = getelementptr [4 x i8], [4 x i8]* %B, i32 0, i32 0<br>
> + %B1 = getelementptr [4 x i8], [4 x i8]* %B, i32 0, i32 1<br>
> + %B2 = getelementptr [4 x i8], [4 x i8]* %B, i32 0, i32 2<br>
> + %B3 = getelementptr [4 x i8], [4 x i8]* %B, i32 0, i32 3<br>
> + store i8 0, i8* %A0<br>
> + store i8 32, i8* %B0<br>
> + store i8 73, i8* %B1<br>
> + store i8 74, i8* %B2<br>
> + store i8 75, i8* %B3<br>
> + br label %loop_begin<br>
> +<br>
> +loop_begin:<br>
> +; CHECK: loop_begin:<br>
> +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A0, i8* %B0,<br>
> i64 4, i32 4, i1 false)<br>
> +<br>
> + %b_val = load i8, i8* %B0<br>
> +<br>
> + ; *B is invariant in loop and limit_val must be hoisted<br>
> + %limit_val_1 = mul i8 %b_val, 3<br>
> + %limit_val = add i8 %limit_val_1, 67<br>
> +<br>
> + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %A0, i8* %B0, i64 4, i32<br>
> 4, i1 false)<br>
> +<br>
> + %exitcond = icmp ugt i8 164, %limit_val<br>
> + br i1 %exitcond, label %after_loop, label %loop_begin<br>
> +<br>
> +after_loop:<br>
> + %b_val_result = load i8, i8* %B0<br>
> + ret i8 %b_val_result<br>
> +}<br>
> +<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
><br>
><br>
<br>
--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>