Bug#810819: gcc-5: misoptimization, "goto out" removed
Hi Matthias,
thanks for the quick answer!
> >During debugging for some strange behaviour in DRBD I got upon this.
>
> please could you recheck with gcc-4.9 (unstable) and gcc-6 (experimental)?
well, wouldn't that make the module incompatible with the running kernel?
I switched the GCC version by modifying
/usr/src/linux-headers-4.3.0-1-amd64/.kernelvariables; "make V=1" correctly
showed the expected version.
== GCC 4.9
1758 err = __send_command(peer_device->connection, device->vnr, sock, P_TRIM, sizeof(*t), NULL, 0);
0x00000000000283f1 <+337>: mov $0x1c,%r9d
0x00000000000283f7 <+343>: mov $0x31,%r8d
0x0000000000028402 <+354>: mov 0x10(%rsp),%rax
0x0000000000028407 <+359>: mov 0x18(%r14),%rdi
0x000000000002840b <+363>: mov 0x68(%rax),%esi
0x000000000002840e <+366>: movl $0x0,0x8(%rsp)
0x0000000000028416 <+374>: movq $0x0,(%rsp)
0x000000000002841e <+382>: callq 0x26750 <__send_command>
0x0000000000028423 <+387>: mov %eax,0x20(%rsp)
1759 goto out;
1760 }
1761 if (dp_flags & DP_WSAME) {
0x00000000000284d6 <+566>: test $0x2,%ah
0x00000000000284d9 <+569>: je 0x2869f <drbd_send_dblock+1023>
== GCC 6
1758 err = __send_command(peer_device->connection, device->vnr, sock, P_TRIM, sizeof(*t), NULL, 0);
0x0000000000029dd7 <+327>: lea 0x200(%rbx),%rcx
0x0000000000029dde <+334>: lea 0x1f8(%rbx),%rdx
0x0000000000029de5 <+341>: mov $0x1c,%r9d
0x0000000000029deb <+347>: mov $0x31,%r8d
0x0000000000029df6 <+358>: mov 0x10(%rsp),%rax
0x0000000000029dfb <+363>: mov 0x18(%r15),%rdi
0x0000000000029dff <+367>: mov 0x68(%rax),%esi
0x0000000000029e02 <+370>: movl $0x0,0x8(%rsp)
0x0000000000029e0a <+378>: movq $0x0,(%rsp)
0x0000000000029e12 <+386>: callq 0x27fd0 <__send_command>
0x0000000000029e17 <+391>: mov %eax,0x20(%rsp)
1759 goto out;
1760 }
1761 if (dp_flags & DP_WSAME) {
0x0000000000029eab <+539>: test $0x2,%ah
0x0000000000029eae <+542>: je 0x2a07f <drbd_send_dblock+1007>
Hrmpf.
Is there some way that GCC can decide that the "goto" is invalid and/or not
needed because the later code must not have any side-effects?
Hard to believe that all the rest of the function can be skipped.
I came across that because *this* call to __send_command() returned
0 (as reported via systemtap), but upon leaving the function it returns an
error code (-5, EIO) - so something must change the "err" inbetween.
And seeing that there's no "jmp" when optimizations are enabled made me
believe in a GCC bug...
Do you see an error in that conclusion?
Here's another output; GCC 5, with
#pragma GCC push_options
#pragma GCC optimize ("O1")
before the function:
1757 err = __send_command(peer_device->connection, device->vnr, sock, P_TRIM, sizeof(*t), NULL, 0);
0x00000000000288cd <+285>: mov 0x68(%r13),%esi
0x00000000000288d1 <+289>: mov 0x18(%rbx),%rdi
0x00000000000288d5 <+293>: movl $0x0,0x8(%rsp)
0x00000000000288dd <+301>: movq $0x0,(%rsp)
0x00000000000288e5 <+309>: mov $0x1c,%r9d
0x00000000000288eb <+315>: mov $0x31,%r8d
0x00000000000288f1 <+321>: callq 0x26860 <__send_command>
0x00000000000288f6 <+326>: mov %eax,%r14d
1758 goto out;
0x00000000000288f9 <+329>: jmpq 0x28a95 <drbd_send_dblock+741>
1759 }
1760 #pragma GCC pop_options
1761 if (dp_flags & DP_WSAME) {
0x00000000000288fe <+334>: test $0x2,%ah
0x0000000000028901 <+337>: je 0x28934 <drbd_send_dblock+388>
Here the jmp is still left in...
Reply to: