Clang incorrectly optimizing out for conditional in Linux kernel

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Clang incorrectly optimizing out for conditional in Linux kernel

Richard Pennington via cfe-dev
Hi,

I am trying to get the Linux kernel to compile and boot using clang.  The code compiles fine, but the kernel does not boot.  It looks like the following macro in mm/vmalloc.c (line 650) is optimizing out the exit condition on the for loop:

#define llist_for_each_entry(pos, node, member)             \
    for ((pos) = llist_entry((node), typeof(*(pos)), member);   \
         &(pos)->member != NULL;                    \
         (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))

Here's the disassembly:

LLVM 4.0

ffffffff811874c3:   48 87 04 25 60 a0 0e    xchg   %rax,0xffffffff820ea060
ffffffff811874ca:   82
ffffffff811874cb:   eb 07                   jmp    ffffffff811874d4 <__purge_vmap_area_lazy+0x294>
ffffffff811874cd:   0f 1f 00                nopl   (%rax)
ffffffff811874d0:   48 8b 40 40             mov    0x40(%rax),%rax
ffffffff811874d4:   48 83 c0 c0             add    $0xffffffffffffffc0,%rax
ffffffff811874d8:   48 8b 08                mov    (%rax),%rcx
ffffffff811874db:   49 3b 4d 00             cmp    0x0(%r13),%rcx
ffffffff811874df:   73 04                   jae    ffffffff811874e5 <__purge_vmap_area_lazy+0x2a5>
ffffffff811874e1:   49 89 4d 00             mov    %rcx,0x0(%r13)
ffffffff811874e5:   48 8b 48 08             mov    0x8(%rax),%rcx
ffffffff811874e9:   49 3b 0e                cmp    (%r14),%rcx
ffffffff811874ec:   76 e2                   jbe    ffffffff811874d0 <__purge_vmap_area_lazy+0x290>
ffffffff811874ee:   49 89 0e                mov    %rcx,(%r14)
ffffffff811874f1:   eb dd                   jmp    ffffffff811874d0 <__purge_vmap_area_lazy+0x290>

GCC

ffffffff811772d6:   48 87 05 2b e7 f6 00    xchg   %rax,0xf6e72b(%rip)        # ffffffff820e5a08 <vmap_purge_list>
ffffffff811772dd:   48 8d 58 c0             lea    -0x40(%rax),%rbx
ffffffff811772e1:   31 c9                   xor    %ecx,%ecx
ffffffff811772e3:   48 85 c0                test   %rax,%rax # <==== init test
ffffffff811772e6:   48 89 da                mov    %rbx,%rdx
ffffffff811772e9:   0f 84 31 02 00 00       je     ffffffff81177520 <__purge_vmap_area_lazy+0x280>
ffffffff811772ef:   90                      nop
ffffffff811772f0:   48 8b 02                mov    (%rdx),%rax
ffffffff811772f3:   49 3b 45 00             cmp    0x0(%r13),%rax
ffffffff811772f7:   73 04                   jae    ffffffff811772fd <__purge_vmap_area_lazy+0x5d>
ffffffff811772f9:   49 89 45 00             mov    %rax,0x0(%r13)
ffffffff811772fd:   48 8b 42 08             mov    0x8(%rdx),%rax
ffffffff81177301:   49 3b 06                cmp    (%r14),%rax
ffffffff81177304:   76 07                   jbe    ffffffff8117730d <__purge_vmap_area_lazy+0x6d>
ffffffff81177306:   49 89 06                mov    %rax,(%r14)
ffffffff81177309:   48 8b 42 08             mov    0x8(%rdx),%rax
ffffffff8117730d:   48 2b 02                sub    (%rdx),%rax
ffffffff81177310:   48 c1 e8 0c             shr    $0xc,%rax
ffffffff81177314:   01 c1                   add    %eax,%ecx
ffffffff81177316:   48 8b 42 40             mov    0x40(%rdx),%rax
ffffffff8117731a:   48 85 c0                test   %rax,%rax  # <==== loop test
ffffffff8117731d:   48 8d 50 c0             lea    -0x40(%rax),%rdx
ffffffff81177321:   75 cd                   jne    ffffffff811772f0 <__purge_vmap_area_lazy+0x50>
--
Derrick McKee
Ph.D. Student at Purdue University

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Clang incorrectly optimizing out for conditional in Linux kernel

Richard Pennington via cfe-dev


On 4/3/17 9:33 AM, Derrick McKee via cfe-dev wrote:

> Hi,
>
> I am trying to get the Linux kernel to compile and boot using clang.
> The code compiles fine, but the kernel does not boot.  It looks like the
> following macro in mm/vmalloc.c (line 650) is optimizing out the exit
> condition on the for loop:
>
> #define llist_for_each_entry(pos, node, member)             \
>     for ((pos) = llist_entry((node), typeof(*(pos)), member);   \
>          &(pos)->member != NULL;

This comparison is tautologically true because it'd be UB to construct
the address if pos were null, and true otherwise.


Jon

         \
>          (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
>

snip

> --
> Derrick McKee
> Ph.D. Student at Purdue University
>
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>

--
Jon Roelofs
[hidden email]
CodeSourcery / Mentor Embedded
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...