[llvm-dev] Where and how to report an optimisation issue that doesn't cause a crash

Momchil Velikov via llvm-dev llvm-dev at lists.llvm.org
Sat Oct 26 13:39:42 PDT 2019


Using the shorter test case:

    struct S {
      int a[3];
      int b;
    };

    int f(struct S *p, int i) {
      if (p->b)
        return 42;

      p->a[i] = 3;
      return p->b;
    }

one can see that the the TBAA metadata loses information about the array
member:

    !4 = !{!"S", !5, i64 0, !7, i64 12}
    !5 = !{!"omnipotent char", !6, i64 0}

The "new struct path TBAA" looks better, it seems to say "there are 12
bytes of
`int`s at offset 0 in struct S"

(Command line was ./bin/clang -target armv7m-eabi -O2 -S y.c -emit-llvm
-Xclang
-new-struct-path-tbaa)


    !3 = !{!4, !7, i64 12, i64 4}
    !4 = !{!5, i64 16, !"S", !7, i64 0, i64 12, !7, i64 12, i64 4}
    !5 = !{!6, i64 1, !"omnipotent char"}
    !6 = !{!"Simple C/C++ TBAA"}
    !7 = !{!5, i64 4, !"int"}
    !8 = !{!7, !7, i64 0, i64 4}

but then, the access tag for the store to the array


    %arrayidx = getelementptr inbounds %struct.S, %struct.S* %p, i32 0, i32
0, i32 %i
    store i32 3, i32* %arrayidx, align 4, !tbaa !8

says just "it's in int" and there it still a redundant load:

    f:
        ldr     r2, [r0, #12]
        cmp     r2, #0
        itt     ne
        movne   r0, #42
        bxne    lr
        movs    r2, #3
        str.w   r2, [r0, r1, lsl #2]
        ldr     r0, [r0, #12]
        bx      lr

So, I manually hacked the metadata too look like:

    !8 = !{!4, !7, i64 0, i64 4}

i.e. as if we access the first element of the array.

Running that through `opt -O2` and `llc` yields:

    f:
        ldr     r2, [r0, #12]
        cmp     r2, #0
        iteee   ne
        movne   r0, #42
        moveq   r2, #3
        streq.w r2, [r0, r1, lsl #2]
        moveq   r0, #0
        bx      lr

That seems like something that Clang can do by itself for access tags for
index
expressions with member arrays: state that they access the offset in the
struct
that corresponds to the first array element, so unknown indices would still
conservatively alias between each other, but not with other struct members.

Thoughts? Pitfalls? I may give it a shot.

~chill

--
Compiler scrub, Arm
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191026/30e7dd3c/attachment.html>


More information about the llvm-dev mailing list