<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Hi Tim,</div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
<div><br>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline"></div>> int16_t a[4];<br>
> int16x4_t b;<br>
><br>
> Global variables a and b are different. a requires a fixed element layout,<br>
> but b has different element layout for big-endian and little-endian,<br>
> although both a and b have different data layout within element.<br>
><br>
> Programmers or tools can't change this, otherwise it would be software<br>
> ecosystem disaster.<br>
><br>
> With your solution, it would introduce a lot of 'strange' code, if use<br>
> ldr/str for variable a in big-endian mode. It's unacceptable for me.<br>
<br>
</div>I really don't believe it would. Could you give an end-to-end example<br>
of such a disaster in my scheme? C code, LLVM IR and assembly? We can<br>
discuss just where we start to disagree about the correct<br>
transformations.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">{code}</div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
// This is scenario 1, and I will give scenario 2 later on</div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">$ cat common.h <br></div></div><div><div class="gmail_default">
<div class="gmail_default"><font face="arial, helvetica, sans-serif">// In a common C head file common.h for programmer p1 and p2 to use</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">#include <stdint.h></font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">extern int16_t a[128];</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">$ cat file1.c </font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">// Programmer p1 writes code in file1</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">#include "common.h"</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">int main()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">{</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    int i;</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">    for (i=0; i<128; i++) {</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">        a[i] = i;</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">    }</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    // And then write a to output file "data" char by char.</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">}</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">$ cat file2.c </font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">// Programmer p2 writes code in file2</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">#include "common.h"</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">#define FAIL 1</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">int main()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">{</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    int i;</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">    // Read from file 'data' to a char by char</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    for (i=0; i<128; i++) {</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">        if (a[i] != i) return FAIL;</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    }</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">}</font></div><div class="gmail_default">{code}</div><div class="gmail_default"><br></div><div class="gmail_default">This is a very common scenario in big-endian programming word, and programmers use the common head file to force the protocol among different modules.</div>
<div class="gmail_default"><br></div><div class="gmail_default">Note that, essentially p1 and p2 don't really care if their code is auto-vectorized or not for each other at all. <span style="font-family:arial,helvetica,sans-serif">For some reason, p1 wants high performance, but p2 wants low power, so the code in file1 is vectorized, while the code in file2 isn't.</span></div>
</div></div></div><div class="gmail_quote">

<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Suppose file1 can be vectorized, and we generate code like below,</div>


<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">{code}</div><div class="gmail_default">
<div class="gmail_default"><div class="gmail_default"><font face="arial, helvetica, sans-serif">; ModuleID = 'file1.c'</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">target triple = "aarch64--linux-gnuabi"</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">@a = external global [128 x i16]</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">; Function Attrs: nounwind</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">define i32 @main() #0 {</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">entry:</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  br label %vector.body</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">vector.body:                                      ; preds = %vector.body, %entry</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  %0 = trunc i64 %index to i32</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  %broadcast.splatinsert6 = insertelement <8 x i32> undef, i32 %0, i32 0</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  %broadcast.splat7 = shufflevector <8 x i32> %broadcast.splatinsert6, <8 x i32> undef, <8 x i32> zeroinitializer</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  %induction8 = add <8 x i32> %broadcast.splat7, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7></font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">  %1 = trunc <8 x i32> %induction8 to <8 x i16></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  %2 = getelementptr inbounds [128 x i16]* @a, i64 0, i64 %index</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  %3 = bitcast i16* %2 to <8 x i16>*</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  store <8 x i16> %1, <8 x i16>* %3, align 2</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  %index.next = add i64 %index, 8</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  %4 = icmp eq i64 %index.next, 128</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">  br i1 %4, label %for.end, label %vector.body, !llvm.loop !1</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">for.end:                                          ; preds = %vector.body</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">  ret i32 0</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">}</font></div><div style="font-family:arial,helvetica,sans-serif;font-size:small">{code}</div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
<br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">So now the question is for "store <8 x i16> %1, <8 x i16>* %3, align 2", what do you want to generate in assembly code?</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">With my solution I want to simply generate st1 for this LLVM IR, simply because it is with 'align 2'. </div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Whit your solution, what do you want to generate?</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">If you want to generate str, I think the result is incorrect, because it would fail in strict mode, and another programmer p2 would see FAIL either.</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">If you want to generate "rev16+ st1", another programmer p2 would see FAIL.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
<br></div></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div><br>
>> whether this is the ldr/str representation or the ld1/st1<br>
>> representation is less important to me,<br>
><br>
><br>
> I think it does matter because ldr/str and ld1/st1 have different data<br>
> layout semantics.<br>
<br>
</div>I'm arguing that we could write a correct compiler that did either.<br>
Which instruction we use should be completely invisible.<br>
<br>
We could actually go further; we could write a compiler where, on<br>
every load and store we make sure the lanes are in the following<br>
order: {3, 1, 4, 5, 2, 6, 7, 0} in the vector register. It would be<br>
completely perverse, but we could make it work if we tried hard<br>
enough.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Of course this is unrealistic and I think it's unnecessary.</div></div><div> </div>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
<div><br>
> Yes, we should avoid mixing them. The issue is how to guarantee a stable<br>
> interface crossing different modules.<br>
> Only using ldr/str for big-endian would introduce a lot of strange code in<br>
> big-endian binary. Given that we have ld1/st1, why do we need those strange<br>
> code?<br>
<br>
</div>Efficiency. </blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline"><br></div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">


If the reason of using ldr/str is only for performance, then I'm OK. I have been thought this was a correctness issue rather than a performance issue only. If this is only for performance benefit, we needn't to discuss any more.<br>


</div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">The advantages of using ldr are:<br>
1. We get to use normal adrp/ldr addressing for globals instead of adrp/add/ld1<br>
2. We don't have to permute vectors being passed or returned from<br>
function calls.<br></blockquote><div> </div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">Do you mean this permutation is introduced by AAPCS64, because it requires to use ldr/str?</div>
</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
<br>
Maybe it's not worth it, or maybe it's worth it in some circumstances<br>
but not others. Perhaps uses within a function outweigh uses across<br>
ABI boundaries and we should attach the rev16 to the ldr instead.<br>
<br>
But I think it's very important that we understand REVs will be needed<br>
on one of them to preserve backend consistency.<br>
<div><br>
> 4) Can you explain when ld1/st1 will be used for big-endian mode with your<br>
> solution? What is the algorithm of generating ld1/st1 for compiler for<br>
> big-endian? Or you are proposing not using ld1/st1 forever?<br>
<br>
</div>I propose: use ld1/st1 when the alignment requirements make it<br>
necessary. Use them with a pattern like:<br>
<br>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline"></div>let Requires = [IsBE] in<br>
def : Pat<(v4i16 (unaligned_load addr:$Rn)), (REV16 (LD1 addr:$Rn))>;<br></blockquote><div><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Well, what unaligned_load is here? I'm confused again! Isn't just to check not total size alignment as I described in my proposal? </div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Instead we want to simply use the pattern below,</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><div class="gmail_default" style="display:inline"><br></div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
<div class="gmail_default" style="display:inline"></div><span style="font-family:arial">let Requires = [IsBE] in</span></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><span style="font-family:arial">def : Pat<(v4i16 (unaligned_load addr:$Rn)), (LD1 addr:$Rn)>;</span></div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><div><br></div><div>If you add rev16 here, you would have to do the action like changing [0] to [3] for element access. This is wired.</div>
<div><br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">


<br>
(We might be able to do some optimisations to fold some of those REVs,<br>
but that would presumably come later).<br>
<div><br>
> If you<br>
> say for this case, the solution would be to use ld1/st1, then is it just to<br>
> check alignment to decide which instruction we should use?<br>
<br>
</div>Yes. Given that ld1/st1 would require an extra REV, we would almost<br>
always prefer ldr/str. The exception being when alignment prohibited<br>
it.<br>
<div><br>
> Anyway, I don't think the solution of doing things like changing [0] to [3]<br>
> and inserting rev instruction by using some 'smart algorithm' in compiler is<br>
> a reasonable choice.<br>
<br>
</div>Fair enough on the [0] to [3], but the REV problem isn't going away:<br>
if we mix ld1/st1 and ldr/str, one of them will have to have a REV<br>
attached as the default situation.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Well. How to mix them? bitcast introduced by auto-vectorizer can't justify it. If it is true in auto-vectorizer, I think it would be a bug, but I doubt auto-vectorizer is generating this. </div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Can you also give me a real case in C code, and show me the IR that we can't simply use ld1/st1 without rev16?</div>


</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
<br>
As I said, I agreed with you about that a couple of weeks ago. Both<br>
representations could be made to work. In this case, the warts are in<br>
function argument passing and bitcasts:<br>
<br>
define i16 @foo(<4 x i16> %in) {<br>
  %elt = extractelement <4 x i16> %in, i32 0<br>
  ret i16 %elt<br>
}<br>
<br>
In the ld1/st1 world, this would have to compile to:<br>
foo:<br>
    rev16 v0.4h, v0.4h<br></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline"><br></div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">


I don't think rev16 is necessary here. As you mentioned we should keep an unique data layout in register. If you don't use rev after ld1, this rev would not be necessary at all.</div></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">


</div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
    umov w0, v0.h[0]<br>
    ret<br>
<br>
Many of those REVs will be foldable of course. In theory. Doing it<br>
well across basic-block boundaries strikes me as a difficult problem<br>
in LLVM.<br>
<div><br>
>     define i16 @foo() {<br>
>       %val = load <4 x i16>* bitcast([4 x i16]* @a to <4 x i16>*)<br>
>       %elt = extractelement <4 x i16> %val, i32 0<br>
>       ret i16 %elt<br>
>     }<br>
><br>
> For this case, I assume optimizer wants to generate it. Then I would say<br>
> optimization is generating invalid code for big-endian.<br>
><br>
</div><div>> I understand auto-vectorizer want to utilize this kind of casting to<br>
> generate code using vector type. To achieve this goal, I think for<br>
> big-endian, we should not only introduce bitcast, but "rev" in LLVM IR.<br>
<br>
</div>That solution is isomorphic to reversing the labelling of lanes in<br>
big-endian (i.e. saying that element 0 has the highest address). It's<br>
not going to happen. People discussed what the LLVM IR should mean a<br>
long time ago and decided element 0 has the lowest address, even in<br>
big-endian.</blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Well, this surprised me. </div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
<br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">The int16x8_t defined in arm_neon.h is a machine vector type, I think, and it intends to map hardware VPR. So for big-endian, all bytes should be reversed if use str follwoing AAPCS64. The vector in LLVM IR only represents symbol, the memory address should not be imposed until load/store time, and big-endian/little-endian should only affect the memory written rather than the content in register.</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Consider the following vectorized version of C code we manually written,</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">{code}</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">
// this is scenario 2.</div><div class="gmail_default"><div class="gmail_default"><font face="arial, helvetica, sans-serif">$ cat common1.h </font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">// In a common C head file common.h for programmer p1 and p2 to use</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">#include <arm_neon.h></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">extern int16x8_t a[16];</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">$ cat fill3.h</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">cat: fill3.h: No such file or directory</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">jialiu01@jialiu01-server:~/test/endian$ cat file3.c </font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">// Programmer p1 writes code in file1</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">#include "common1.h"</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">int main()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">{</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    int i;</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">    int16_t j;</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    for (i=0; i<16; i++) {</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">        j = 8*i;</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">        a[i] = (int16x8_t){j, j+1, j+2, j+3, j+4, j+5, j+6, j+7};</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">    }</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    // And then write a to output file "data" char by char.</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">}</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">$ cat file4.c </font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">// Programmer p2 writes code in file2</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">#include "common1.h"</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">#define FAIL 1</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">int main()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">{</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    int i;</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">    int j;</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    // Read from file 'data' to a char by char</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">    for (i=0; i<16; i++) {</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">        for (j=0; j<8; j++) {</font></div>
<div class="gmail_default"><font face="arial, helvetica, sans-serif">            if (a[i][j] != i*8+j) return FAIL;</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">        }</font></div><div class="gmail_default">
<font face="arial, helvetica, sans-serif">    }</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">}</font></div><div style="font-family:arial,helvetica,sans-serif;font-size:small">{code}</div>
</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">I think it's a valid one. With my solution, it's very simple, str will be used file3.c, while ldr will be used for file4.c, because they have the following LLVM IR generated respectively.</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">store <8 x i16> %vecinit27, <8 x i16>* %arrayidx, align 16   // in LLVM IR of file3.c</font><br>
</div><div class="gmail_default"><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div class="gmail_default"><span style="font-family:arial,helvetica,sans-serif">%0 = load <8 x i16>* %arrayidx, align 16  // in LLVM IR of file4.c</span><br>
</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">We needn't rev16 here. Note that the byte ordering in the data file being transferred between programmer p1 and p2 will be different from the cases I gave by common.h/file1.c/file2.c. </div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">In the file transferred of scenario 1, the char ordering in disk should be like 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ..., 127. (let's ignore the ordering difference for inside each number for big-endian and little-endian, because we are not discussing about that). In the file transferred of scenario 2, the char order in disk should be like 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, ... , 127,..., 121, 120.</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Of course, you can also exchange data without using file, and link the binaries generated by p1 and p2, but the result would be the same.</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Can you explain to me what instructions are going to generated with your solution?</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small"><br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">
PPC SIMD support (& possibly Mips) has been implemente<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
</div>d<br>

around this decision.<br></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">I'm not sure if PPC is doing this way. Maybe you can prove me around this. But even if other targets is implementing things this way, it can't simply arguing it is a correct one. With my two-cents experience of software engineering, sometimes people may use a ugly solution to solve a simple problem.</div>
</div><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">Thanks,</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small">-Jiangning</div>
<br></div></div></div></div>