I recently upgraded that machine to gcc 4.6. We may need to fix the testsuite to build with newer GCCs.<div><br></div><div>Nick<br><br><div class="gmail_quote">On 11 May 2011 13:39, Jim Grosbach <span dir="ltr"><<a href="mailto:grosbach@apple.com">grosbach@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">There's something odd going on with that buildbot. There are compile-time errors from the system host compiler on tramp3d, for example, as well as errors from the clang under test.<br>
<div><div></div><div class="h5"><br>
On May 11, 2011, at 11:37 AM, Evan Cheng wrote:<br>
<br>
> Rafael, can you provide more information? Which buildbot? What's the symptom? I noticed <a href="http://google1.osuosl.org:8011/builders/clang-x86_64-linux-fnt" target="_blank">http://google1.osuosl.org:8011/builders/clang-x86_64-linux-fnt</a> is still red.<br>
><br>
> Evan<br>
><br>
> On May 10, 2011, at 8:27 PM, Rafael Espindola wrote:<br>
><br>
>> Author: rafael<br>
>> Date: Tue May 10 22:27:17 2011<br>
>> New Revision: 131176<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=131176&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=131176&view=rev</a><br>
>> Log:<br>
>> Revert 131172 as it is causing clang to miscompile itself. I will try<br>
>> to provide a reduced testcase.<br>
>><br>
>> Removed:<br>
>> llvm/trunk/test/CodeGen/X86/hoist-common.ll<br>
>> Modified:<br>
>> llvm/trunk/lib/CodeGen/BranchFolding.cpp<br>
>> llvm/trunk/lib/CodeGen/BranchFolding.h<br>
>> llvm/trunk/lib/CodeGen/IfConversion.cpp<br>
>><br>
>> Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=131176&r1=131175&r2=131176&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=131176&r1=131175&r2=131176&view=diff</a><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original)<br>
>> +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Tue May 10 22:27:17 2011<br>
>> @@ -41,7 +41,6 @@<br>
>> STATISTIC(NumDeadBlocks, "Number of dead blocks removed");<br>
>> STATISTIC(NumBranchOpts, "Number of branches optimized");<br>
>> STATISTIC(NumTailMerge , "Number of block tails merged");<br>
>> -STATISTIC(NumHoist , "Number of times common instructions are hoisted");<br>
>><br>
>> static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",<br>
>> cl::init(cl::BOU_UNSET), cl::Hidden);<br>
>> @@ -66,7 +65,7 @@<br>
>> public:<br>
>> static char ID;<br>
>> explicit BranchFolderPass(bool defaultEnableTailMerge)<br>
>> - : MachineFunctionPass(ID), BranchFolder(defaultEnableTailMerge, true) {}<br>
>> + : MachineFunctionPass(ID), BranchFolder(defaultEnableTailMerge) {}<br>
>><br>
>> virtual bool runOnMachineFunction(MachineFunction &MF);<br>
>> virtual const char *getPassName() const { return "Control Flow Optimizer"; }<br>
>> @@ -87,14 +86,12 @@<br>
>> }<br>
>><br>
>><br>
>> -BranchFolder::BranchFolder(bool defaultEnableTailMerge, bool CommonHoist) {<br>
>> +BranchFolder::BranchFolder(bool defaultEnableTailMerge) {<br>
>> switch (FlagEnableTailMerge) {<br>
>> case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break;<br>
>> case cl::BOU_TRUE: EnableTailMerge = true; break;<br>
>> case cl::BOU_FALSE: EnableTailMerge = false; break;<br>
>> }<br>
>> -<br>
>> - EnableHoistCommonCode = CommonHoist;<br>
>> }<br>
>><br>
>> /// RemoveDeadBlock - Remove the specified dead machine basic block from the<br>
>> @@ -189,10 +186,9 @@<br>
>><br>
>> bool MadeChangeThisIteration = true;<br>
>> while (MadeChangeThisIteration) {<br>
>> - MadeChangeThisIteration = TailMergeBlocks(MF);<br>
>> - MadeChangeThisIteration |= OptimizeBranches(MF);<br>
>> - if (EnableHoistCommonCode)<br>
>> - MadeChangeThisIteration |= HoistCommonCode(MF);<br>
>> + MadeChangeThisIteration = false;<br>
>> + MadeChangeThisIteration |= TailMergeBlocks(MF);<br>
>> + MadeChangeThisIteration |= OptimizeBranches(MF);<br>
>> MadeChange |= MadeChangeThisIteration;<br>
>> }<br>
>><br>
>> @@ -914,8 +910,7 @@<br>
>> // Make sure blocks are numbered in order<br>
>> MF.RenumberBlocks();<br>
>><br>
>> - for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();<br>
>> - I != E; ) {<br>
>> + for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) {<br>
>> MachineBasicBlock *MBB = I++;<br>
>> MadeChange |= OptimizeBlock(MBB);<br>
>><br>
>> @@ -1344,253 +1339,3 @@<br>
>><br>
>> return MadeChange;<br>
>> }<br>
>> -<br>
>> -//===----------------------------------------------------------------------===//<br>
>> -// Hoist Common Code<br>
>> -//===----------------------------------------------------------------------===//<br>
>> -<br>
>> -/// HoistCommonCode - Hoist common instruction sequences at the start of basic<br>
>> -/// blocks to their common predecessor.<br>
>> -/// NOTE: This optimization does not update live-in information so it must be<br>
>> -/// run after all passes that require correct liveness information.<br>
>> -bool BranchFolder::HoistCommonCode(MachineFunction &MF) {<br>
>> - bool MadeChange = false;<br>
>> - for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ) {<br>
>> - MachineBasicBlock *MBB = I++;<br>
>> - MadeChange |= HoistCommonCodeInSuccs(MBB);<br>
>> - }<br>
>> -<br>
>> - return MadeChange;<br>
>> -}<br>
>> -<br>
>> -/// findFalseBlock - BB has a fallthrough. Find its 'false' successor given<br>
>> -/// its 'true' successor.<br>
>> -static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,<br>
>> - MachineBasicBlock *TrueBB) {<br>
>> - for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),<br>
>> - E = BB->succ_end(); SI != E; ++SI) {<br>
>> - MachineBasicBlock *SuccBB = *SI;<br>
>> - if (SuccBB != TrueBB)<br>
>> - return SuccBB;<br>
>> - }<br>
>> - return NULL;<br>
>> -}<br>
>> -<br>
>> -/// findHoistingInsertPosAndDeps - Find the location to move common instructions<br>
>> -/// in successors to. The location is ususally just before the terminator,<br>
>> -/// however if the terminator is a conditional branch and its previous<br>
>> -/// instruction is the flag setting instruction, the previous instruction is<br>
>> -/// the preferred location. This function also gathers uses and defs of the<br>
>> -/// instructions from the insertion point to the end of the block. The data is<br>
>> -/// used by HoistCommonCodeInSuccs to ensure safety.<br>
>> -static<br>
>> -MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB,<br>
>> - const TargetInstrInfo *TII,<br>
>> - const TargetRegisterInfo *TRI,<br>
>> - SmallSet<unsigned,4> &Uses,<br>
>> - SmallSet<unsigned,4> &Defs) {<br>
>> - MachineBasicBlock::iterator Loc = MBB->getFirstTerminator();<br>
>> - if (!TII->isUnpredicatedTerminator(Loc))<br>
>> - return MBB->end();<br>
>> -<br>
>> - for (unsigned i = 0, e = Loc->getNumOperands(); i != e; ++i) {<br>
>> - const MachineOperand &MO = Loc->getOperand(i);<br>
>> - if (!MO.isReg())<br>
>> - continue;<br>
>> - unsigned Reg = MO.getReg();<br>
>> - if (!Reg)<br>
>> - continue;<br>
>> - if (MO.isUse()) {<br>
>> - Uses.insert(Reg);<br>
>> - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)<br>
>> - Uses.insert(*AS);<br>
>> - } else if (!MO.isDead())<br>
>> - // Don't try to hoist code in the rare case the terminator defines a<br>
>> - // register that is later used.<br>
>> - return MBB->end();<br>
>> - }<br>
>> -<br>
>> - if (Uses.empty())<br>
>> - return Loc;<br>
>> - if (Loc == MBB->begin())<br>
>> - return MBB->end();<br>
>> -<br>
>> - // The terminator is probably a conditional branch, try not to separate the<br>
>> - // branch from condition setting instruction.<br>
>> - MachineBasicBlock::iterator PI = Loc;<br>
>> - --PI;<br>
>> - while (PI != MBB->begin() && Loc->isDebugValue())<br>
>> - --PI;<br>
>> -<br>
>> - bool IsDef = false;<br>
>> - for (unsigned i = 0, e = PI->getNumOperands(); !IsDef && i != e; ++i) {<br>
>> - const MachineOperand &MO = PI->getOperand(i);<br>
>> - if (!MO.isReg() || MO.isUse())<br>
>> - continue;<br>
>> - unsigned Reg = MO.getReg();<br>
>> - if (!Reg)<br>
>> - continue;<br>
>> - if (Uses.count(Reg))<br>
>> - IsDef = true;<br>
>> - }<br>
>> - if (!IsDef)<br>
>> - // The condition setting instruction is not just before the conditional<br>
>> - // branch.<br>
>> - return Loc;<br>
>> -<br>
>> - // Be conservative, don't insert instruction above something that may have<br>
>> - // side-effects. And since it's potentially bad to separate flag setting<br>
>> - // instruction from the conditional branch, just abort the optimization<br>
>> - // completely.<br>
>> - // Also avoid moving code above predicated instruction since it's hard to<br>
>> - // reason about register liveness with predicated instruction.<br>
>> - bool DontMoveAcrossStore = true;<br>
>> - if (!PI->isSafeToMove(TII, 0, DontMoveAcrossStore) ||<br>
>> - TII->isPredicated(PI))<br>
>> - return MBB->end();<br>
>> -<br>
>> -<br>
>> - // Find out what registers are live. Note this routine is ignoring other live<br>
>> - // registers which are only used by instructions in successor blocks.<br>
>> - for (unsigned i = 0, e = PI->getNumOperands(); i != e; ++i) {<br>
>> - const MachineOperand &MO = PI->getOperand(i);<br>
>> - if (!MO.isReg())<br>
>> - continue;<br>
>> - unsigned Reg = MO.getReg();<br>
>> - if (!Reg)<br>
>> - continue;<br>
>> - if (MO.isUse()) {<br>
>> - Uses.insert(Reg);<br>
>> - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)<br>
>> - Uses.insert(*AS);<br>
>> - } else {<br>
>> - if (Uses.count(Reg)) {<br>
>> - Uses.erase(Reg);<br>
>> - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)<br>
>> - Uses.erase(*SR); // Use getSubRegisters to be conservative<br>
>> - Defs.insert(Reg);<br>
>> - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)<br>
>> - Defs.insert(*AS);<br>
>> - }<br>
>> - }<br>
>> - }<br>
>> -<br>
>> - return PI;<br>
>> -}<br>
>> -<br>
>> -/// HoistCommonCodeInSuccs - If the successors of MBB has common instruction<br>
>> -/// sequence at the start of the function, move the instructions before MBB<br>
>> -/// terminator if it's legal.<br>
>> -bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) {<br>
>> - MachineBasicBlock *TBB = 0, *FBB = 0;<br>
>> - SmallVector<MachineOperand, 4> Cond;<br>
>> - if (TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, true) || !TBB || Cond.empty())<br>
>> - return false;<br>
>> -<br>
>> - if (!FBB) FBB = findFalseBlock(MBB, TBB);<br>
>> - if (!FBB)<br>
>> - // Malformed bcc? True and false blocks are the same?<br>
>> - return false;<br>
>> -<br>
>> - // Restrict the optimization to cases where MBB is the only predecessor,<br>
>> - // it is an obvious win.<br>
>> - if (TBB->pred_size() > 1 || FBB->pred_size() > 1)<br>
>> - return false;<br>
>> -<br>
>> - // Find a suitable position to hoist the common instructions to. Also figure<br>
>> - // out which registers are used or defined by instructions from the insertion<br>
>> - // point to the end of the block.<br>
>> - SmallSet<unsigned, 4> Uses, Defs;<br>
>> - MachineBasicBlock::iterator Loc =<br>
>> - findHoistingInsertPosAndDeps(MBB, TII, TRI, Uses, Defs);<br>
>> - if (Loc == MBB->end())<br>
>> - return false;<br>
>> -<br>
>> - SmallSet<unsigned, 4> LocalDefs;<br>
>> - unsigned NumDups = 0;<br>
>> - MachineBasicBlock::iterator TIB = TBB->begin();<br>
>> - MachineBasicBlock::iterator FIB = FBB->begin();<br>
>> - MachineBasicBlock::iterator TIE = TBB->end();<br>
>> - MachineBasicBlock::iterator FIE = FBB->end();<br>
>> - while (TIB != TIE && FIB != FIE) {<br>
>> - // Skip dbg_value instructions. These do not count.<br>
>> - if (TIB->isDebugValue()) {<br>
>> - while (TIB != TIE && TIB->isDebugValue())<br>
>> - ++TIB;<br>
>> - if (TIB == TIE)<br>
>> - break;<br>
>> - }<br>
>> - if (FIB->isDebugValue()) {<br>
>> - while (FIB != FIE && FIB->isDebugValue())<br>
>> - ++FIB;<br>
>> - if (FIB == FIE)<br>
>> - break;<br>
>> - }<br>
>> - if (!TIB->isIdenticalTo(FIB))<br>
>> - break;<br>
>> -<br>
>> - if (TII->isPredicated(TIB))<br>
>> - // Hard to reason about register liveness with predicated instruction.<br>
>> - break;<br>
>> -<br>
>> - bool IsSafe = true;<br>
>> - for (unsigned i = 0, e = TIB->getNumOperands(); i != e; ++i) {<br>
>> - const MachineOperand &MO = TIB->getOperand(i);<br>
>> - if (!MO.isReg())<br>
>> - continue;<br>
>> - unsigned Reg = MO.getReg();<br>
>> - if (!Reg)<br>
>> - continue;<br>
>> - if (MO.isDef()) {<br>
>> - if (Uses.count(Reg)) {<br>
>> - // Avoid clobbering a register that's used by the instruction at<br>
>> - // the point of insertion.<br>
>> - IsSafe = false;<br>
>> - break;<br>
>> - }<br>
>> - if (!MO.isDead() && Defs.count(Reg)) {<br>
>> - // Don't hoist the instruction if the def would be clobber by the<br>
>> - // instruction at the point insertion. FIXME: This is overly<br>
>> - // conservative. It should be possible to hoist the instructions<br>
>> - // in BB2 in the following example:<br>
>> - // BB1:<br>
>> - // r1, eflag = op1 r2, r3<br>
>> - // brcc eflag<br>
>> - //<br>
>> - // BB2:<br>
>> - // r1 = op2, ...<br>
>> - // = op3, r1<kill><br>
>> - IsSafe = false;<br>
>> - break;<br>
>> - }<br>
>> - LocalDefs.insert(Reg);<br>
>> - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR)<br>
>> - LocalDefs.insert(*SR);<br>
>> - } else if (!LocalDefs.count(Reg)) {<br>
>> - if (Defs.count(Reg)) {<br>
>> - // Use is defined by the instruction at the point of insertion.<br>
>> - IsSafe = false;<br>
>> - break;<br>
>> - }<br>
>> - }<br>
>> - }<br>
>> - if (!IsSafe)<br>
>> - break;<br>
>> -<br>
>> - bool DontMoveAcrossStore = true;<br>
>> - if (!TIB->isSafeToMove(TII, 0, DontMoveAcrossStore))<br>
>> - break;<br>
>> -<br>
>> - ++NumDups;<br>
>> - ++TIB;<br>
>> - ++FIB;<br>
>> - }<br>
>> -<br>
>> - if (!NumDups)<br>
>> - return false;<br>
>> -<br>
>> - MBB->splice(Loc, TBB, TBB->begin(), TIB);<br>
>> - FBB->erase(FBB->begin(), FIB);<br>
>> - ++NumHoist;<br>
>> - return true;<br>
>> -}<br>
>><br>
>> Modified: llvm/trunk/lib/CodeGen/BranchFolding.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=131176&r1=131175&r2=131176&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.h?rev=131176&r1=131175&r2=131176&view=diff</a><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/CodeGen/BranchFolding.h (original)<br>
>> +++ llvm/trunk/lib/CodeGen/BranchFolding.h Tue May 10 22:27:17 2011<br>
>> @@ -19,10 +19,11 @@<br>
>> class RegScavenger;<br>
>> class TargetInstrInfo;<br>
>> class TargetRegisterInfo;<br>
>> + template<typename T> class SmallVectorImpl;<br>
>><br>
>> class BranchFolder {<br>
>> public:<br>
>> - explicit BranchFolder(bool defaultEnableTailMerge, bool CommonHoist);<br>
>> + explicit BranchFolder(bool defaultEnableTailMerge);<br>
>><br>
>> bool OptimizeFunction(MachineFunction &MF,<br>
>> const TargetInstrInfo *tii,<br>
>> @@ -84,7 +85,6 @@<br>
>> std::vector<SameTailElt> SameTails;<br>
>><br>
>> bool EnableTailMerge;<br>
>> - bool EnableHoistCommonCode;<br>
>> const TargetInstrInfo *TII;<br>
>> const TargetRegisterInfo *TRI;<br>
>> MachineModuleInfo *MMI;<br>
>> @@ -110,9 +110,6 @@<br>
>> bool OptimizeBlock(MachineBasicBlock *MBB);<br>
>> void RemoveDeadBlock(MachineBasicBlock *MBB);<br>
>> bool OptimizeImpDefsBlock(MachineBasicBlock *MBB);<br>
>> -<br>
>> - bool HoistCommonCode(MachineFunction &MF);<br>
>> - bool HoistCommonCodeInSuccs(MachineBasicBlock *MBB);<br>
>> };<br>
>> }<br>
>><br>
>><br>
>> Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=131176&r1=131175&r2=131176&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=131176&r1=131175&r2=131176&view=diff</a><br>
>> ==============================================================================<br>
>> --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original)<br>
>> +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Tue May 10 22:27:17 2011<br>
>> @@ -265,7 +265,7 @@<br>
>> if (!TII) return false;<br>
>><br>
>> // Tail merge tend to expose more if-conversion opportunities.<br>
>> - BranchFolder BF(true, false);<br>
>> + BranchFolder BF(true);<br>
>> bool BFChange = BF.OptimizeFunction(MF, TII,<br>
>> MF.getTarget().getRegisterInfo(),<br>
>> getAnalysisIfAvailable<MachineModuleInfo>());<br>
>> @@ -399,7 +399,7 @@<br>
>> BBAnalysis.clear();<br>
>><br>
>> if (MadeChange && IfCvtBranchFold) {<br>
>> - BranchFolder BF(false, false);<br>
>> + BranchFolder BF(false);<br>
>> BF.OptimizeFunction(MF, TII,<br>
>> MF.getTarget().getRegisterInfo(),<br>
>> getAnalysisIfAvailable<MachineModuleInfo>());<br>
>><br>
>> Removed: llvm/trunk/test/CodeGen/X86/hoist-common.ll<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hoist-common.ll?rev=131175&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hoist-common.ll?rev=131175&view=auto</a><br>
>> ==============================================================================<br>
>> --- llvm/trunk/test/CodeGen/X86/hoist-common.ll (original)<br>
>> +++ llvm/trunk/test/CodeGen/X86/hoist-common.ll (removed)<br>
>> @@ -1,28 +0,0 @@<br>
>> -; RUN: llc < %s -march=x86-64 | FileCheck %s<br>
>> -<br>
>> -; Common "xorb al, al" instruction in the two successor blocks should be<br>
>> -; moved to the entry block above the test + je.<br>
>> -<br>
>> -; rdar://9145558<br>
>> -<br>
>> -define zeroext i1 @t(i32 %c) nounwind ssp {<br>
>> -entry:<br>
>> -; CHECK: t:<br>
>> -; CHECK: xorb %al, %al<br>
>> -; CHECK: test<br>
>> -; CHECK: je<br>
>> - %tobool = icmp eq i32 %c, 0<br>
>> - br i1 %tobool, label %return, label %if.then<br>
>> -<br>
>> -if.then:<br>
>> -; CHECK: callq<br>
>> - %call = tail call zeroext i1 (...)* @foo() nounwind<br>
>> - br label %return<br>
>> -<br>
>> -return:<br>
>> -; CHECK: ret<br>
>> - %retval.0 = phi i1 [ %call, %if.then ], [ false, %entry ]<br>
>> - ret i1 %retval.0<br>
>> -}<br>
>> -<br>
>> -declare zeroext i1 @foo(...)<br>
>><br>
>><br>
>> _______________________________________________<br>
>> llvm-commits mailing list<br>
>> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>