[LLVMdev] Loops Prevent Function Pointer Inlining?

Zinovy Nis zinovy.nis at gmail.com
Wed Sep 24 08:18:35 PDT 2014


Looks a bit similar to http://llvm.org/bugs/show_bug.cgi?id=20801

2014-09-24 16:51 GMT+04:00 Nicholas White <n.j.white at gmail.com>:
> Hi - I've been trying to track down why a function pointer isn't being
> inlined in some cases, and have nailed it down to the following repro:
>
> struct s
> {
>     int (*cmp) (const void *, const void *);
>     int its[2];
> };
>
> static int __uint_compare(const void *e1, const void *e2)
> {
>     const int *i1 = e1;
>     const int *i2 = e2;
>     return *i2 - *i1;
> }
>
> int main()
> {
>     struct s hp;
>     hp.cmp = __uint_compare;
>     hp.its[0] = 1;
>     hp.its[1] = 2;
>
>     for (int i = 0; i < 1; i++)
>     {
>         int cmp = hp.cmp(&hp.its[i], &hp.its[i + 1]);
>         if(cmp < 0)
>         {
>             return 1;
>         }
>     }
>
>     return 0;
> }
>
> I've compiled it (as test2.c) with the following commands, and have
> attached the unoptimised and optimised outputs.
>
> clang  -O0 -S -emit-llvm -o test2.ll test2.c
> opt -O3 -debug -S test2.ll > test2.opt.ll 2>log2
>
> However, if I replace the main function with the code below (test.c),
> the function call to __uint_compare is inlined and the whole function
> is correctly replaced with a "ret i32 0".
>
> int main()
> {
>     struct s hp;
>     hp.cmp = __uint_compare;
>     hp.its[0] = 1;
>     hp.its[1] = 2;
>
>     int cmp = hp.cmp(&hp.its[0], &hp.its[1]);
>     if(cmp < 0)
>     {
>         return 1;
>     }
>
>     return 0;
> }
>
> As you can see, the first example always executes the for-loop exactly
> once, so the semantics of both examples are identical. From looking at
> the differences in the two (attached) log files, it seems like the
> problem's in the GVN pass, as only the log for the second example has:
>
> GVN iteration: 0
> GVN removed:   %5 = load i32 (i8*, i8*)** %1, align 8
> GVN iteration: 1
>
> Is this analysis correct? Or is some other pass getting tricked by the
> for loop (maybe because the load & store are no longer in the same
> basic block)? I was thinking of trying to fix it myself, but am not
> sure exactly where in the codebase I should get started.
>
> Thanks -
>
> Nick
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



More information about the llvm-dev mailing list