<div dir="ltr">Thanks Hal!  That was exactly it.  But a mystery remains: why did we choose to vectorize here when we knew we'd have to expand it later?</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Feb 3, 2014 at 9:33 AM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">----- Original Message -----<br>
> From: "Hal Finkel" <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>><br>
> To: "Raul Silvera" <<a href="mailto:rsilvera@google.com">rsilvera@google.com</a>><br>
> Cc: "Chandler Carruth" <<a href="mailto:chandlerc@gmail.com">chandlerc@gmail.com</a>>, "llvm-commits" <<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a>><br>
</div><div><div class="h5">> Sent: Monday, February 3, 2014 11:24:26 AM<br>
> Subject: Re: [llvm] r200576 - [SLPV] Recognize vectorizable intrinsics        during  SLP vectorization and<br>
><br>
> ----- Original Message -----<br>
> > From: "Hal Finkel" <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>><br>
> > To: "Raul Silvera" <<a href="mailto:rsilvera@google.com">rsilvera@google.com</a>><br>
> > Cc: "Chandler Carruth" <<a href="mailto:chandlerc@gmail.com">chandlerc@gmail.com</a>>, "llvm-commits"<br>
> > <<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a>><br>
> > Sent: Monday, February 3, 2014 11:13:41 AM<br>
> > Subject: Re: [llvm] r200576 - [SLPV] Recognize vectorizable<br>
> > intrinsics  during  SLP vectorization and<br>
> ><br>
> > ----- Original Message -----<br>
> > > From: "Raul Silvera" <<a href="mailto:rsilvera@google.com">rsilvera@google.com</a>><br>
> > > To: "Reid Kleckner" <<a href="mailto:rnk@google.com">rnk@google.com</a>><br>
> > > Cc: "Chandler Carruth" <<a href="mailto:chandlerc@gmail.com">chandlerc@gmail.com</a>>, "llvm-commits"<br>
> > > <<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a>><br>
> > > Sent: Monday, February 3, 2014 10:51:38 AM<br>
> > > Subject: Re: [llvm] r200576 - [SLPV] Recognize vectorizable<br>
> > > intrinsics during SLP vectorization and<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > Thank you Reid. Have you reverted the change?<br>
> > ><br>
> > ><br>
> > > I think the alternatives are to disable vectorization of bswap on<br>
> > > 32-bit or teach llvm how to do the expansion.<br>
> > ><br>
> > ><br>
> > > I'm using the same code as the Loop vectorizer to decide what to<br>
> > > vectorize, which makes me wonder if the same issue could be hit<br>
> > > with<br>
> > > loop vectorization. I'll investigate a bit further and figure out<br>
> > > what to do next.<br>
> > ><br>
> ><br>
> > Actually, this is a bit strange. X86ISelLowering.cpp has:<br>
> ><br>
> >   for (int i = MVT::FIRST_VECTOR_VALUETYPE;<br>
> >            i <= MVT::LAST_VECTOR_VALUETYPE; ++i) {<br>
> >     MVT VT = (MVT::SimpleValueType)i;<br>
> >     ...<br>
> >     setOperationAction(ISD::BSWAP, VT, Expand);<br>
> >     ...<br>
> >   }<br>
> ><br>
> > and so there should be no problem with lowering a vector bswap for<br>
> > any vector type, and if there is, that seems like a SDAG bug.<br>
><br>
> Or if I had read more carefully, I would have seen that this must be<br>
> the case (the code ends up in SelectionDAGLegalize::ExpandBSWAP,<br>
> which only handles scalar types). Looks like we just don't handle<br>
> this in LegalizeVectorOps.<br>
<br>
</div></div>I fixed this in r200705.<br>
<span class="HOEnZb"><font color="#888888"><br>
 -Hal<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
> That having been said, there must also be another problem because<br>
> BSWAP is marked as expand, and so it should have a high cost. Maybe<br>
> vectorizing the rest of the code makes it worthwhile, but this<br>
> should be double-checked.<br>
><br>
>  -Hal<br>
><br>
> ><br>
> >  -Hal<br>
> ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > On Fri, Jan 31, 2014 at 5:40 PM, Reid Kleckner < <a href="mailto:rnk@google.com">rnk@google.com</a> ><br>
> > > wrote:<br>
> > ><br>
> > ><br>
> > ><br>
> > > Hey Raul,<br>
> > ><br>
> > ><br>
> > > This patch broke the 32-bit self-host build. The x86 backend<br>
> > > claims<br>
> > > that the legalizer knows how to expand bswap intrinsics on vector<br>
> > > types, but this is not the case. Running llc the test case I gave<br>
> > > produces:<br>
> > ><br>
> > > Unhandled Expand type in BSWAP!<br>
> > > UNREACHABLE executed at<br>
> > > ..\lib\CodeGen\SelectionDAG\LegalizeDAG.cpp:2537!<br>
> > ><br>
> > ><br>
> > > I'm going to revert this for now, but what should happen is that<br>
> > > we<br>
> > > should learn how to expand bswap on vectors.<br>
> > ><br>
> > ><br>
> > > Reid<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > On Fri, Jan 31, 2014 at 5:17 PM, Reid Kleckner < <a href="mailto:rnk@google.com">rnk@google.com</a> ><br>
> > > wrote:<br>
> > ><br>
> > ><br>
> > ><br>
> > > This change caused us to vectorize bswap, which we then try to<br>
> > > expand<br>
> > > on i686, which hits an unreachable. Running llc on this repros:<br>
> > ><br>
> > ><br>
> > ><br>
> > > declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>) #8<br>
> > > define <2 x i64> @foo(<2 x i64> %v) {<br>
> > > %s = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %v)<br>
> > > ret <2 x i64> %s<br>
> > > }<br>
> > > attributes #8 = { nounwind readnone }<br>
> > ><br>
> > ><br>
> > > I don't have a reduced test case of input to the SLP vectorizer<br>
> > > yet<br>
> > > because I'm new to reducing LLVM IR.<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > On Fri, Jan 31, 2014 at 1:14 PM, Chandler Carruth <<br>
> > > <a href="mailto:chandlerc@gmail.com">chandlerc@gmail.com</a> > wrote:<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > Author: chandlerc<br>
> > > Date: Fri Jan 31 15:14:40 2014<br>
> > > New Revision: 200576<br>
> > ><br>
> > > URL: <a href="http://llvm.org/viewvc/llvm-project?rev=200576&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=200576&view=rev</a><br>
> > > Log:<br>
> > > [SLPV] Recognize vectorizable intrinsics during SLP vectorization<br>
> > > and<br>
> > > transform accordingly. Based on similar code from Loop<br>
> > > vectorization.<br>
> > > Subsequent commits will include vectorization of function calls<br>
> > > to<br>
> > > vector intrinsics and form function calls to vector library<br>
> > > calls.<br>
> > ><br>
> > > Patch by Raul Silvera! (Much delayed due to my not running<br>
> > > dcommit)<br>
> > ><br>
> > > Added:<br>
> > > llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll<br>
> > > Modified:<br>
> > > llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp<br>
> > ><br>
> > > Modified: llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp<br>
> > > URL:<br>
> > > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp?rev=200576&r1=200575&r2=200576&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp?rev=200576&r1=200575&r2=200576&view=diff</a><br>

> > > ==============================================================================<br>
> > > --- llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp<br>
> > > (original)<br>
> > > +++ llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp Fri Jan<br>
> > > 31<br>
> > > 15:14:40 2014<br>
> > > @@ -947,6 +947,39 @@ void BoUpSLP::buildTree_rec(ArrayRef<Val<br>
> > > buildTree_rec(Operands, Depth + 1);<br>
> > > return;<br>
> > > }<br>
> > > + case Instruction::Call: {<br>
> > > + // Check if the calls are all to the same vectorizable<br>
> > > intrinsic.<br>
> > > + IntrinsicInst *II = dyn_cast<IntrinsicInst>(VL[0]);<br>
> > > + if (II==NULL) {<br>
> > > + newTreeEntry(VL, false);<br>
> > > + DEBUG(dbgs() << "SLP: Non-vectorizable call.\n");<br>
> > > + return;<br>
> > > + }<br>
> > > +<br>
> > > + Intrinsic::ID ID = II->getIntrinsicID();<br>
> > > +<br>
> > > + for (unsigned i = 1, e = VL.size(); i != e; ++i) {<br>
> > > + IntrinsicInst *II2 = dyn_cast<IntrinsicInst>(VL[i]);<br>
> > > + if (!II2 || II2->getIntrinsicID() != ID) {<br>
> > > + newTreeEntry(VL, false);<br>
> > > + DEBUG(dbgs() << "SLP: mismatched calls:" << *II << "!=" <<<br>
> > > *VL[i]<br>
> > > + << "\n");<br>
> > > + return;<br>
> > > + }<br>
> > > + }<br>
> > > +<br>
> > > + newTreeEntry(VL, true);<br>
> > > + for (unsigned i = 0, e = II->getNumArgOperands(); i != e; ++i)<br>
> > > {<br>
> > > + ValueList Operands;<br>
> > > + // Prepare the operand vector.<br>
> > > + for (unsigned j = 0; j < VL.size(); ++j) {<br>
> > > + IntrinsicInst *II2 = dyn_cast<IntrinsicInst>(VL[j]);<br>
> > > + Operands.push_back(II2->getArgOperand(i));<br>
> > > + }<br>
> > > + buildTree_rec(Operands, Depth + 1);<br>
> > > + }<br>
> > > + return;<br>
> > > + }<br>
> > > default:<br>
> > > newTreeEntry(VL, false);<br>
> > > DEBUG(dbgs() << "SLP: Gathering unknown instruction.\n");<br>
> > > @@ -1072,6 +1105,30 @@ int BoUpSLP::getEntryCost(TreeEntry *E)<br>
> > > int VecStCost = TTI->getMemoryOpCost(Instruction::Store, VecTy,<br>
> > > 1,<br>
> > > 0);<br>
> > > return VecStCost - ScalarStCost;<br>
> > > }<br>
> > > + case Instruction::Call: {<br>
> > > + CallInst *CI = cast<CallInst>(VL0);<br>
> > > + IntrinsicInst *II = cast<IntrinsicInst>(CI);<br>
> > > + Intrinsic::ID ID = II->getIntrinsicID();<br>
> > > +<br>
> > > + // Calculate the cost of the scalar and vector calls.<br>
> > > + SmallVector<Type*, 4> ScalarTys, VecTys;<br>
> > > + for (unsigned op = 0, opc = II->getNumArgOperands(); op!= opc;<br>
> > > ++op) {<br>
> > > + ScalarTys.push_back(CI->getArgOperand(op)->getType());<br>
> > > +<br>
> > > VecTys.push_back(VectorType::get(CI->getArgOperand(op)->getType(),<br>
> > > + VecTy->getNumElements()));<br>
> > > + }<br>
> > > +<br>
> > > + int ScalarCallCost = VecTy->getNumElements() *<br>
> > > + TTI->getIntrinsicInstrCost(ID, ScalarTy, ScalarTys);<br>
> > > +<br>
> > > + int VecCallCost = TTI->getIntrinsicInstrCost(ID, VecTy,<br>
> > > VecTys);<br>
> > > +<br>
> > > + DEBUG(dbgs() << "SLP: Call cost "<< VecCallCost -<br>
> > > ScalarCallCost<br>
> > > + << " (" << VecCallCost << "-" << ScalarCallCost << ")"<br>
> > > + << " for " << *II << "\n");<br>
> > > +<br>
> > > + return VecCallCost - ScalarCallCost;<br>
> > > + }<br>
> > > default:<br>
> > > llvm_unreachable("Unknown instruction");<br>
> > > }<br>
> > > @@ -1086,10 +1143,10 @@ bool BoUpSLP::isFullyVectorizableTinyTre<br>
> > > return false;<br>
> > ><br>
> > > // Gathering cost would be too much for tiny trees.<br>
> > > - if (VectorizableTree[0].NeedToGather ||<br>
> > > VectorizableTree[1].NeedToGather)<br>
> > > - return false;<br>
> > > + if (VectorizableTree[0].NeedToGather ||<br>
> > > VectorizableTree[1].NeedToGather)<br>
> > > + return false;<br>
> > ><br>
> > > - return true;<br>
> > > + return true;<br>
> > > }<br>
> > ><br>
> > > int BoUpSLP::getTreeCost() {<br>
> > > @@ -1555,6 +1612,32 @@ Value *BoUpSLP::vectorizeTree(TreeEntry<br>
> > > E->VectorizedValue = S;<br>
> > > return propagateMetadata(S, E->Scalars);<br>
> > > }<br>
> > > + case Instruction::Call: {<br>
> > > + CallInst *CI = cast<CallInst>(VL0);<br>
> > > +<br>
> > > + setInsertPointAfterBundle(E->Scalars);<br>
> > > + std::vector<Value *> OpVecs;<br>
> > > + for (int j = 0, e = CI->getNumArgOperands(); j < e; ++j) {<br>
> > > + ValueList OpVL;<br>
> > > + for (int i = 0, e = E->Scalars.size(); i < e; ++i) {<br>
> > > + CallInst *CEI = cast<CallInst>(E->Scalars[i]);<br>
> > > + OpVL.push_back(CEI->getArgOperand(j));<br>
> > > + }<br>
> > > +<br>
> > > + Value *OpVec = vectorizeTree(OpVL);<br>
> > > + DEBUG(dbgs() << "SLP: OpVec[" << j << "]: " << *OpVec << "\n");<br>
> > > + OpVecs.push_back(OpVec);<br>
> > > + }<br>
> > > +<br>
> > > + Module *M = F->getParent();<br>
> > > + IntrinsicInst *II = cast<IntrinsicInst>(CI);<br>
> > > + Intrinsic::ID ID = II->getIntrinsicID();<br>
> > > + Type *Tys[] = { VectorType::get(CI->getType(),<br>
> > > E->Scalars.size())<br>
> > > };<br>
> > > + Function *CF = Intrinsic::getDeclaration(M, ID, Tys);<br>
> > > + Value *V = Builder.CreateCall(CF, OpVecs);<br>
> > > + E->VectorizedValue = V;<br>
> > > + return V;<br>
> > > + }<br>
> > > default:<br>
> > > llvm_unreachable("unknown inst");<br>
> > > }<br>
> > ><br>
> > > Added: llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll<br>
> > > URL:<br>
> > > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll?rev=200576&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll?rev=200576&view=auto</a><br>

> > > ==============================================================================<br>
> > > --- llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll<br>
> > > (added)<br>
> > > +++ llvm/trunk/test/Transforms/SLPVectorizer/X86/intrinsic.ll Fri<br>
> > > Jan<br>
> > > 31 15:14:40 2014<br>
> > > @@ -0,0 +1,75 @@<br>
> > > +; RUN: opt < %s -basicaa -slp-vectorizer -slp-threshold=-999<br>
> > > -dce<br>
> > > -S<br>
> > > -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck<br>
> > > %s<br>
> > > +<br>
> > > +target datalayout =<br>
> > > "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-S128"<br>
> > > +target triple = "x86_64-apple-macosx10.8.0"<br>
> > > +<br>
> > > +declare double @llvm.fabs.f64(double) nounwind readnone<br>
> > > +<br>
> > > +;CHECK-LABEL: @vec_fabs_f64(<br>
> > > +;CHECK: load <2 x double><br>
> > > +;CHECK: load <2 x double><br>
> > > +;CHECK: call <2 x double> @llvm.fabs.v2f64<br>
> > > +;CHECK: store <2 x double><br>
> > > +;CHECK: ret<br>
> > > +define void @vec_fabs_f64(double* %a, double* %b, double* %c) {<br>
> > > +entry:<br>
> > > + %i0 = load double* %a, align 8<br>
> > > + %i1 = load double* %b, align 8<br>
> > > + %mul = fmul double %i0, %i1<br>
> > > + %call = tail call double @llvm.fabs.f64(double %mul) nounwind<br>
> > > readnone<br>
> > > + %arrayidx3 = getelementptr inbounds double* %a, i64 1<br>
> > > + %i3 = load double* %arrayidx3, align 8<br>
> > > + %arrayidx4 = getelementptr inbounds double* %b, i64 1<br>
> > > + %i4 = load double* %arrayidx4, align 8<br>
> > > + %mul5 = fmul double %i3, %i4<br>
> > > + %call5 = tail call double @llvm.fabs.f64(double %mul5) nounwind<br>
> > > readnone<br>
> > > + store double %call, double* %c, align 8<br>
> > > + %arrayidx5 = getelementptr inbounds double* %c, i64 1<br>
> > > + store double %call5, double* %arrayidx5, align 8<br>
> > > + ret void<br>
> > > +}<br>
> > > +<br>
> > > +declare float @llvm.copysign.f32(float, float) nounwind readnone<br>
> > > +<br>
> > > +;CHECK-LABEL: @vec_copysign_f32(<br>
> > > +;CHECK: load <4 x float><br>
> > > +;CHECK: load <4 x float><br>
> > > +;CHECK: call <4 x float> @llvm.copysign.v4f32<br>
> > > +;CHECK: store <4 x float><br>
> > > +;CHECK: ret<br>
> > > +define void @vec_copysign_f32(float* %a, float* %b, float*<br>
> > > noalias<br>
> > > %c) {<br>
> > > +entry:<br>
> > > + %0 = load float* %a, align 4<br>
> > > + %1 = load float* %b, align 4<br>
> > > + %call0 = tail call float @llvm.copysign.f32(float %0, float %1)<br>
> > > nounwind readnone<br>
> > > + store float %call0, float* %c, align 4<br>
> > > +<br>
> > > + %ix2 = getelementptr inbounds float* %a, i64 1<br>
> > > + %2 = load float* %ix2, align 4<br>
> > > + %ix3 = getelementptr inbounds float* %b, i64 1<br>
> > > + %3 = load float* %ix3, align 4<br>
> > > + %call1 = tail call float @llvm.copysign.f32(float %2, float %3)<br>
> > > nounwind readnone<br>
> > > + %c1 = getelementptr inbounds float* %c, i64 1<br>
> > > + store float %call1, float* %c1, align 4<br>
> > > +<br>
> > > + %ix4 = getelementptr inbounds float* %a, i64 2<br>
> > > + %4 = load float* %ix4, align 4<br>
> > > + %ix5 = getelementptr inbounds float* %b, i64 2<br>
> > > + %5 = load float* %ix5, align 4<br>
> > > + %call2 = tail call float @llvm.copysign.f32(float %4, float %5)<br>
> > > nounwind readnone<br>
> > > + %c2 = getelementptr inbounds float* %c, i64 2<br>
> > > + store float %call2, float* %c2, align 4<br>
> > > +<br>
> > > + %ix6 = getelementptr inbounds float* %a, i64 3<br>
> > > + %6 = load float* %ix6, align 4<br>
> > > + %ix7 = getelementptr inbounds float* %b, i64 3<br>
> > > + %7 = load float* %ix7, align 4<br>
> > > + %call3 = tail call float @llvm.copysign.f32(float %6, float %7)<br>
> > > nounwind readnone<br>
> > > + %c3 = getelementptr inbounds float* %c, i64 3<br>
> > > + store float %call3, float* %c3, align 4<br>
> > > +<br>
> > > + ret void<br>
> > > +}<br>
> > > +<br>
> > > +<br>
> > > +<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>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > --<br>
> > ><br>
> > ><br>
> > > Raúl E. Silvera<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>
> > --<br>
> > Hal Finkel<br>
> > Assistant Computational Scientist<br>
> > Leadership Computing Facility<br>
> > Argonne National Laboratory<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>
> --<br>
> Hal Finkel<br>
> Assistant Computational Scientist<br>
> Leadership Computing Facility<br>
> Argonne National Laboratory<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>
--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<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>