<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace;font-size:small">Using the shorter test case:<br><br>    struct S {<br>      int a[3];<br>      int b;<br>    };<br>    <br>    int f(struct S *p, int i) {<br>      if (p->b)<br>        return 42;<br>    <br>      p->a[i] = 3;<br>      return p->b;<br>    }<br><br>one can see that the the TBAA metadata loses information about the array member:<br><br>    !4 = !{!"S", !5, i64 0, !7, i64 12}<br>    !5 = !{!"omnipotent char", !6, i64 0}<br><br>The "new struct path TBAA" looks better, it seems to say "there are 12 bytes of<br>`int`s at offset 0 in struct S"<br><br>(Command line was ./bin/clang -target armv7m-eabi -O2 -S y.c -emit-llvm -Xclang<br>-new-struct-path-tbaa)<br><br><br>    !3 = !{!4, !7, i64 12, i64 4}<br>    !4 = !{!5, i64 16, !"S", !7, i64 0, i64 12, !7, i64 12, i64 4}<br>    !5 = !{!6, i64 1, !"omnipotent char"}<br>    !6 = !{!"Simple C/C++ TBAA"}<br>    !7 = !{!5, i64 4, !"int"}<br>    !8 = !{!7, !7, i64 0, i64 4}<br><br>but then, the access tag for the store to the array<br><br><br>    %arrayidx = getelementptr inbounds %struct.S, %struct.S* %p, i32 0, i32 0, i32 %i<br>    store i32 3, i32* %arrayidx, align 4, !tbaa !8<br><br>says just "it's in int" and there it still a redundant load:<br><br>    f:<br>        ldr     r2, [r0, #12]<br>        cmp     r2, #0<br>        itt     ne<br>        movne   r0, #42<br>        bxne    lr<br>        movs    r2, #3<br>        str.w   r2, [r0, r1, lsl #2]<br>        ldr     r0, [r0, #12]<br>        bx      lr<br><br>So, I manually hacked the metadata too look like:<br><br>    !8 = !{!4, !7, i64 0, i64 4}<br><br>i.e. as if we access the first element of the array.<br><br>Running that through `opt -O2` and `llc` yields:<br><br>    f:<br>        ldr     r2, [r0, #12]<br>        cmp     r2, #0<br>        iteee   ne<br>        movne   r0, #42<br>        moveq   r2, #3<br>        streq.w r2, [r0, r1, lsl #2]<br>        moveq   r0, #0<br>        bx      lr<br><br>That seems like something that Clang can do by itself for access tags for index<br>expressions with member arrays: state that they access the offset in the struct<br>that corresponds to the first array element, so unknown indices would still<br>conservatively alias between each other, but not with other struct members.<br><br>Thoughts? Pitfalls? I may give it a shot.<br></div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small"><br></div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small">~chill</div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small"><br></div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small">--</div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small">Compiler scrub, Arm</div><div class="gmail_default" style="font-family:monospace,monospace;font-size:small"><br></div></div></div>