<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><p style="color:#000;">On April 30, 2014 at 10:10:52 PM, Philip Reames (<a href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>) wrote:</p> <div><blockquote type="cite" class="clean_bq" style="color: rgb(0, 0, 0); font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);"><span><div><div></div><div>In case anyone is curious, I went ahead and wrote down a quick list of<span class="Apple-converted-space"> </span><br>high level language semantics for integer division. You can find it here:<span class="Apple-converted-space"> </span><br>http://www.philipreames.com/Blog/2014/05/01/semantics-of-2s-completement-integer-division/<span class="Apple-converted-space"> </span><br><br>I'd be curious if I've missed languages with interesting semantics, or<span class="Apple-converted-space"> </span><br>have gotten something wrong.<span class="Apple-converted-space"> </span><br><br>Michael - Do you have a link for the JavaScript "|0" semantics you<span class="Apple-converted-space"> </span><br>mentioned? I'm unfamiliar with those and couldn't find a good source.<span class="Apple-converted-space"> </span><br>I'll also note that your JavaScript semantics disagreed with my reading<span class="Apple-converted-space"> </span><br>of the spec. Can you explain where I went wrong?<span class="Apple-converted-space"> </span></div></div></span></blockquote></div><p>The part that you're missing is that x|0 means "convert x to an int value the ToInt algorithm and then perform a 32-bit bitwise or with 32-bit int zero, and then convert the result back to a 'number' (i.e. double)".  The ToInt algorithm is specified, see sec. 9.5 of the ECMA-262 spec.  The way to think of it is that if you could imagine an infinite-bit number with a radix point, you'd represent the double as such a number and then take the 32 bits immediately to the left (ones bit and above) of the radix point as the integer.  If the incoming double was anything special (infinity or NaN) then the result is 0.</p><p>-Filip</p><p><br></p><div><blockquote type="cite" class="clean_bq" style="color: rgb(0, 0, 0); font-family: Helvetica, Arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);"><span><div><div><br><br>Philip<span class="Apple-converted-space"> </span><br><br>On 04/26/2014 02:11 PM, Michael Zolotukhin wrote:<span class="Apple-converted-space"> </span><br>> Hi,<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Thanks to everybody for the very informative feedback! Due to difference in timezones, I usually miss the most active time of discussions, however I’ll try to cover the raised questions here and share my vision on them.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Generally speaking, we are trying to find answers to the following two questions:<span class="Apple-converted-space"> </span><br>> o   Are these intrinsics useful in general?<span class="Apple-converted-space"> </span><br>> o  If yes, when to lower them to actual IR/DAG?<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> In a nutshell, my answers are:<span class="Apple-converted-space"> </span><br>> o    Yes, they are useful, and useful for all targets. Not only for ARM64, where they are especially useful.<span class="Apple-converted-space"> </span><br>> o  After loop optimizations but before lowering IR to DAG. Currently it’s in CodeGenPrepare, but we might lower them before that if there is any need in this.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> I'll try to explain why I think so. For the beginning, let's consider a simple expression div=x/y in different languages and write the corresponding IR with use of the intrinsics (here I omit types for conciseness, assuming result type of the safe.sdiv intrinsic being {i32, i1, i1}) :<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** C/C-like ***<span class="Apple-converted-space"> </span><br>> %div = sdiv %x, %y<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** Java, Go ***<span class="Apple-converted-space"> </span><br>> %divr = call %safe.sdiv(%x, %y)<span class="Apple-converted-space"> </span><br>> %div = extractvalue %divr, 0<span class="Apple-converted-space"> </span><br>> %divbyzero_bit = extractvalue %divr, 1<span class="Apple-converted-space"> </span><br>> br i1 %divbyzero_bit, label %throw, label %normal<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** JavaScript, with “|0” ***<span class="Apple-converted-space"> </span><br>> %divr = call %safe.sdiv(%x, %y)<span class="Apple-converted-space"> </span><br>> %div = extractvalue %divr, 0<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** JavaScript without “|0”, Ruby and maybe others ***<span class="Apple-converted-space"> </span><br>> %divr = call %safe.sdiv(%x, %y)<span class="Apple-converted-space"> </span><br>> %div = extractvalue %divr, 0<span class="Apple-converted-space"> </span><br>> %divbyzero_bit = extractvalue %divr, 1<span class="Apple-converted-space"> </span><br>> %ovf_bit = extractvalue %divr, 2<span class="Apple-converted-space"> </span><br>> %exceptional_case_bit = or %ovf_bit, %divbyzero_bit<span class="Apple-converted-space"> </span><br>> br i1 %exceptional_case_bit, label %handle_exceptional_case, label %normal<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Now let’s write the IR for the same expression without the intrinsics:<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** C/C-like ***<span class="Apple-converted-space"> </span><br>> %div = sdiv %x, %y<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** Java, Go ***<span class="Apple-converted-space"> </span><br>> %divbyzero_bit = cmp %y, 0<span class="Apple-converted-space"> </span><br>> br i1 %divbyzero_bit, label %throw, label %normal<span class="Apple-converted-space"> </span><br>> normal:<span class="Apple-converted-space"> </span><br>> %div = sdiv %x, %y<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** JavaScript, with “|0” ***<span class="Apple-converted-space"> </span><br>> %divbyzero_bit = cmp %y, 0<span class="Apple-converted-space"> </span><br>> br i1 %divbyzero_bit, label %division_by_zero, label %chkovf<span class="Apple-converted-space"> </span><br>> division_by_zero:<span class="Apple-converted-space"> </span><br>> br label %end<span class="Apple-converted-space"> </span><br>> chkovf:<span class="Apple-converted-space"> </span><br>> %tmin_bit = cmp %x, min<T><span class="Apple-converted-space"> </span><br>> %minus_one_bit = cmp %y, -1<span class="Apple-converted-space"> </span><br>> %ovf_bit = and %tmin_bit, %minus_one_bit<span class="Apple-converted-space"> </span><br>> br i1 %ovf_bit, label %ovf, label %normal<span class="Apple-converted-space"> </span><br>> ovf:<span class="Apple-converted-space"> </span><br>> br label %end<span class="Apple-converted-space"> </span><br>> normal:<span class="Apple-converted-space"> </span><br>> %div.0 = sdiv %x, %y<span class="Apple-converted-space"> </span><br>> br label %end<span class="Apple-converted-space"> </span><br>> end:<span class="Apple-converted-space"> </span><br>> %div = phi [%div.0, %normal], [min<T>, %ovf], [0, %division_by_zero]<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> *** JavaScript without “|0”, Ruby and maybe others ***<span class="Apple-converted-space"> </span><br>> %divbyzero_bit = cmp %y, 0<span class="Apple-converted-space"> </span><br>> br i1 %divbyzero_bit, label %throw, label %chkovf<span class="Apple-converted-space"> </span><br>> chkovf:<span class="Apple-converted-space"> </span><br>> %tmin_bit = cmp %x, min<T><span class="Apple-converted-space"> </span><br>> %minus_one_bit = cmp %y, -1<span class="Apple-converted-space"> </span><br>> %ovf_bit = and %tmin_bit, %minus_one_bit<span class="Apple-converted-space"> </span><br>> br i1 %ovf_bit, label %ovf, label %normal<span class="Apple-converted-space"> </span><br>> ovf:<span class="Apple-converted-space"> </span><br>> ; Special handling of min<T>/-1: converting to BigInt, double or something other<span class="Apple-converted-space"> </span><br>> unreachable<span class="Apple-converted-space"> </span><br>> normal:<span class="Apple-converted-space"> </span><br>> %div.0 = sdiv %x, %y<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> As one can see, if the intrinsic is lowered to some CFG (i.e. on x86), there is nor loss neither win: due to the implemented optimizations the final code would be roughly the same as in the case with explicitly written CFG.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> If the intrinsic could be directly lowered to a single instruction (i.e. on ARM64 and if we don’t bother about divz/ovf-flag), use of the intrinsic would definitely be beneficial - that takes place for the <JavaScript, with “|0”> case.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> That might make one think that the intrinsics are useful only for ARM64, and in general aren’t that useful at all. But in fact even when it can’t be lowered to a single instruction, keeping the control flow ‘inside’ the intrinsic till its lowering might be beneficial. For instance, loop passes work much better on loops without control flow: IndVars might be a good example of such pass. And, for instance, it seems much easier to vectorize a loop with call to one of these intrinsics than vectorize a loop with explicitly created control flow (and it could become even worse if there are several calls to the intrinsics in the same loop).<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> In some cases we might want to lower these intrinsics earlier than in CGP - as Reid mentioned, it could help us to hoist checks out of loops. That’s true but we need to keep in mind possible disadvantages of such early lowering (see previous paragraph). But in general I don’t see any problems with allowing earlier lowering.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> As for extending the result structure to keep one more flag (being that i2 instead of i1, or one more i1 flag) - that seems fine, and both options {iN, i2} and {iN, i1, i1} look good to me.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Now, why not to lower these intrinsics even later? Almost for all targets we want to get very similar CFG, and I don’t see any benefits of duplicating very similar code all across different backends. Even on ARM64 we need to have control flow in some cases (e.g. for Java) - so we actually win nothing from making lowering completely target-specific.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> I hope that covers the raised concerns, at least to some extent. Does that sound reasonable enough? If so, I’ll prepare and post here an updated version of the patch.<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> Thanks,<span class="Apple-converted-space"> </span><br>> Michael<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> On Apr 26, 2014, at 4:04 AM, Andrew Trick <atrick@apple.com> wrote:<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>>> On Apr 25, 2014, at 2:21 PM, Eric Christopher <echristo@gmail.com> wrote:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>>>> In short, I agree with your observations that these intrinsics are not an<span class="Apple-converted-space"> </span><br>>>>> obvious slam-dunk compared to making the explicit control flow, but I think<span class="Apple-converted-space"> </span><br>>>>> that the intrinsics do give enough flexibility on the LLVM side that it<span class="Apple-converted-space"> </span><br>>>>> would be great if front-ends used them rather than rolling the control flow<span class="Apple-converted-space"> </span><br>>>>> themselves.<span class="Apple-converted-space"> </span><br>>>>><span class="Apple-converted-space"> </span><br>>>> The problem is that then we have 2 problems: All targets (except for<span class="Apple-converted-space"> </span><br>>>> arm64) then have to lower the intrinsic as the first thing they do<span class="Apple-converted-space"> </span><br>>>> (giving us a TTI pass as the first thing in the pipeline) to take<span class="Apple-converted-space"> </span><br>>>> advantage of the information later during optimization, _and_ we have<span class="Apple-converted-space"> </span><br>>>> to plumb all of the work optimizing the intrinsic as well giving us a<span class="Apple-converted-space"> </span><br>>>> situation where we've now split our optimization efforts as well as<span class="Apple-converted-space"> </span><br>>>> the pain of maintaining an intrinsic that's useful for a single<span class="Apple-converted-space"> </span><br>>>> target.<span class="Apple-converted-space"> </span><br>>>><span class="Apple-converted-space"> </span><br>>>> I really think that this is just solidifying my position that the<span class="Apple-converted-space"> </span><br>>>> intrinsic is a bad idea and that this should be done as later<span class="Apple-converted-space"> </span><br>>>> optimizations.<span class="Apple-converted-space"> </span><br>>> The goal of the intrinsic wasn't stated clearly.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> This intrinsic isn't particularly necessary for any specific frontend<span class="Apple-converted-space"> </span><br>>> or architecture. I think the LLVM community would benefit from a<span class="Apple-converted-space"> </span><br>>> canonical way to represent well-defined integer division. We don't<span class="Apple-converted-space"> </span><br>>> need to add an IR instruction, because it's fine for most optimization<span class="Apple-converted-space"> </span><br>>> passes to ignore these operations. A target independent intrinsic<span class="Apple-converted-space"> </span><br>>> works well as long as:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> - It cleanly captures the language level semantics.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> - It facilitates mid-level optimization.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> - It naturally lowers into ideal code both on architectures that trap<span class="Apple-converted-space"> </span><br>>> (x86) and those that don't (arm).<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> To summarize my understanding of the concerns:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> (1) The semantics of the safe.div intrinsic need to be useful for the<span class="Apple-converted-space"> </span><br>>> Language/ISA Matrix that LLVMers care about.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> At canonical IR level, the intrinsic is useful by eliminating control<span class="Apple-converted-space"> </span><br>>> flow merges and representing divide-by-zero and/or signed overflow in<span class="Apple-converted-space"> </span><br>>> a canonical form:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> %res = call {i32, i1} @llvm.safe.sdiv.i32(i32 %a, i32 %b)<span class="Apple-converted-space"> </span><br>>> %bit = extractvalue {i32, i1} %res, 1<span class="Apple-converted-space"> </span><br>>> br i1 %bit, label %trap, label %continue<span class="Apple-converted-space"> </span><br>>> trap:<span class="Apple-converted-space"> </span><br>>> call ...<span class="Apple-converted-space"> </span><br>>> unreachable<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> continue:<span class="Apple-converted-space"> </span><br>>> %div = extractvalue {i32, i1} %res, 0<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> The original proposal fails to achieve this because the common case of<span class="Apple-converted-space"> </span><br>>> Java/Go would require a check in the slow-path to differentiate<span class="Apple-converted-space"> </span><br>>> divide-by-zero from signed overflow. That should be fixed by<span class="Apple-converted-space"> </span><br>>> generalizing the intrinsic so that the two conditions are distinct:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> %res = call {i32, i1, i1} @llvm.safe.sdiv.i32(i32 %a, i32 %b)<span class="Apple-converted-space"> </span><br>>> %div0 = extractvalue {i32, i1} %res, 1<span class="Apple-converted-space"> </span><br>>> br i1 %div0, label %trap, label %checkovf<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> checkovf:<span class="Apple-converted-space"> </span><br>>> %ovf = extractvalue {i32, i1} %res, 2<span class="Apple-converted-space"> </span><br>>> br i1 %div0, label %trap, label %continue<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> trap:<span class="Apple-converted-space"> </span><br>>> call ...<span class="Apple-converted-space"> </span><br>>> unreachable<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> continue:<span class="Apple-converted-space"> </span><br>>> %div = extractvalue {i32, i1} %res, 0<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> ...or some variation of the above. I don't have a personal stake in this.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> (2) The safe.div intrinsic inhibits generic code motion and Correlated<span class="Apple-converted-space"> </span><br>>> Value Prop based optimization.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> This goes both ways.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> CVP could miss out on cases unless we teach it about the semantics of<span class="Apple-converted-space"> </span><br>>> the intrinsics. Correct me if I'm wrong, but I don't think this would<span class="Apple-converted-space"> </span><br>>> actually be too difficult.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> OTOH, with the intrinsics, it would be easy to write a simple<span class="Apple-converted-space"> </span><br>>> optimization pass that hoists and combines checks along the domtree.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> After divide-by-zero optimization, you would have something like:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> %res = call {i32, i1, i1} @llvm.safe.sdiv.i32(i32 %a, i32 %b)<span class="Apple-converted-space"> </span><br>>> %div0 = extractvalue {i32, i1} %res, 1<span class="Apple-converted-space"> </span><br>>> br i1 %div0, label %trap, label %continue<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> trap:<span class="Apple-converted-space"> </span><br>>> # No call here!<span class="Apple-converted-space"> </span><br>>> unreachable<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> continue:<span class="Apple-converted-space"> </span><br>>> %div = extractvalue {i32, i1} %res, 0<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> And the branch to trap just goes away at some point.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> Now considering Reid's LICM example:<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> for (int i = 0; i < n; ++i) {<span class="Apple-converted-space"> </span><br>>> if (b == 0) c[i] = 0;<span class="Apple-converted-space"> </span><br>>> else if (b == -1 && a[i] == INT_MIN) c[i] = INT_MIN;<span class="Apple-converted-space"> </span><br>>> else c[i] = a[i] / b;<span class="Apple-converted-space"> </span><br>>> }<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> Simply put, if we want to unswitch this code for x86, then we need a<span class="Apple-converted-space"> </span><br>>> TTI pass to lower the intrinsic. On the other hand, I believe it is<span class="Apple-converted-space"> </span><br>>> more important to eliminate the control flow within the loop to aid<span class="Apple-converted-space"> </span><br>>> loop analysis and other optimizations. So we still want the front end<span class="Apple-converted-space"> </span><br>>> to emit the intrinsic, we just may eventually want it lowered earlier<span class="Apple-converted-space"> </span><br>>> than CGP. I don't think this issue has any bearing on the intrinsic's<span class="Apple-converted-space"> </span><br>>> LangRef spec.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> There was some comparison made to iload/istore, which I don't<span class="Apple-converted-space"> </span><br>>> follow:<span class="Apple-converted-space"> </span><br>>> - subsuming loads and stores into another instruction is really scary<span class="Apple-converted-space"> </span><br>>> considering how much logic we have for analyzing the side effects of<span class="Apple-converted-space"> </span><br>>> memory access.<span class="Apple-converted-space"> </span><br>>> - there is no benefit to IR optimization to the iload/istore intruction.<span class="Apple-converted-space"> </span><br>>> - it is easy to detect null checked load/stores in IR at any point.<span class="Apple-converted-space"> </span><br>>> - it is very rare that a platform would want to resume from trapping load/store.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> (3) The safe.div intrinsic is a target-specific codegen optimization.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> Regardless of the target, we want to eliminate control flow merges in<span class="Apple-converted-space"> </span><br>>> all cases, and completely eliminate control flow when we don't have<span class="Apple-converted-space"> </span><br>>> trapping semantics. To do this, we need an intrinsic at canonical IR<span class="Apple-converted-space"> </span><br>>> level. Clearly it should be a target independent intrinsic<span class="Apple-converted-space"> </span><br>>> since *some* optimizations/analyses want to be aware of it.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> Even ignoring the rationale above, supporting codegen with a<span class="Apple-converted-space"> </span><br>>> target-specific intrinsic would minimally require the DAG builder to<span class="Apple-converted-space"> </span><br>>> match this<span class="Apple-converted-space"> </span><br>>> "if (b != 0) ? ((a != INT_MIN || b != -1) ? a / b : INT_MIN) : 0)"<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> after all optimizations have had their way with it. A big problem here<span class="Apple-converted-space"> </span><br>>> is that there are actually many different forms of this expression and<span class="Apple-converted-space"> </span><br>>> surrounding control flow, depending on the frontend's integer division<span class="Apple-converted-space"> </span><br>>> semantics. We would have to recognize all the variations of checking for<span class="Apple-converted-space"> </span><br>>> divide-by-zero and/or overflow, trapping and/or producing a certain<span class="Apple-converted-space"> </span><br>>> constant, branching or selecting values. This is obviously terrible<span class="Apple-converted-space"> </span><br>>> from an engineering standpoint.<span class="Apple-converted-space"> </span><br>>><span class="Apple-converted-space"> </span><br>>> -Andy<span class="Apple-converted-space"> </span><br>>> _______________________________________________<span class="Apple-converted-space"> </span><br>>> LLVM Developers mailing list<span class="Apple-converted-space"> </span><br>>> LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu<span class="Apple-converted-space"> </span><br>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev<span class="Apple-converted-space"> </span><br>><span class="Apple-converted-space"> </span><br>> _______________________________________________<span class="Apple-converted-space"> </span><br>> LLVM Developers mailing list<span class="Apple-converted-space"> </span><br>> LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu<span class="Apple-converted-space"> </span><br>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev<span class="Apple-converted-space"> </span><br><br>_______________________________________________<span class="Apple-converted-space"> </span><br>LLVM Developers mailing list<span class="Apple-converted-space"> </span><br>LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu<span class="Apple-converted-space"> </span><br>http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev<span class="Apple-converted-space"> </span><br></div></div></span></blockquote></div></body></html>