http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58234
Bug ID: 58234 Summary: In-line asm version of __FD_ZERO in /usr/include/bits/select.h Product: gcc Version: 4.4.7 Status: UNCONFIRMED Severity: normal Priority: P3 Component: inline-asm Assignee: unassigned at gcc dot gnu.org Reporter: baker at usgs dot gov I encountered a run-time error using the -check=uninit Intel icc compiler option on Linux: Run-Time Check Failure: The variable '__d1' is being used without being initialized I tracked the problem to the FD_ZERO macro, which is ultimately expanded using the __FD_ZERO macro in /usr/include/bits/select.h. A very simple program will trigger the run-time failure: #include <sys/select.h> int main( void ) { fd_set rfds; FD_ZERO( &rfds ); return 0; } Compiled with: # icc -check=uninit intel.c The fix is to disable the in-line asm code for __FD_ZERO; -no-gcc will suffice: # icc -no-gcc -check=uninit intel.c That is fine for this case. But the code I am working with needs other GNUC header options that also get disabled when -no-gcc is used. If I add -no-gcc, I get lots of compilation errors. I realize this is not technically a GCC library/headers error. I think the Intel icc compiler does not properly account for in-line asm side-effects in its uninitialized variable tracking. However, I decided to see if I could make the __FD_ZERO macro asm work. I was able to rearrange the in-line asm for a workaround in this case. I think this is an improvement, and also cures a subtle flaw in the original that (luckily) makes absolutely no difference. The original __FD_ZERO macro definition (in /usr/include/bits/select.h) is: # define __FD_ZERO(fdsp) \ do { \ int __d0, __d1; \ __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS \ : "=c" (__d0), "=D" (__d1) \ : "a" (0), "0" (sizeof (fd_set) \ / sizeof (__fd_mask)), \ "1" (&__FDS_BITS (fdsp)[0]) \ : "memory"); \ } while (0) I cannot tell exactly where in the expansion the Intel run-time error occurs -- gdb shows ?? for the backtrace beyond the Intel __intel_rtc_uninit_use() service routine (compiled with -g): (gdb) bt #0 0x00130430 in __kernel_vsyscall () #1 0x001a3b11 in raise () from /lib/libc.so.6 #2 0x001a53ea in abort () from /lib/libc.so.6 #3 0x080489e1 in __intel_rtc_uninit_use () #4 0x00000001 in ?? () #5 0x00000000 in ?? () The assembly language generated by gcc -O0 (-m32 or -m64) always includes a store into __d0 and __d1 after the execution of the stosl/stosq instruction. Maybe it is that store which is tripping up the Intel code. I rewrote the asm to remove __d0 and __d1, since they go out-of-scope anyway after the asm executes: # define __FD_ZERO(fdsp) \ do { \ __asm__ __volatile__ ("cld; rep; " __FD_ZERO_STOS \ : \ : "a" (0), \ "c" (sizeof (fd_set) / sizeof (__fd_mask)), \ "D" (&__FDS_BITS (fdsp)[0]) \ : "memory"); \ } while (0) This generated slightly different code, which I believe is correct. Here is the original assembly output for gcc -m32 and gcc -m64: Original __FD_ZERO, gcc -m32 .file "junk.c" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp pushl %edi subl $144, %esp movl $0, %eax movl $32, %ecx leal -140(%ebp), %edx movl %edx, %edi #APP # 45 "junk.c" 1 cld; rep; stosl # 0 "" 2 #NO_APP movl %edi, %edx movl %ecx, -12(%ebp) movl %edx, -8(%ebp) movl $0, %eax addl $144, %esp popl %edi popl %ebp ret .size main, .-main .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)" .section .note.GNU-stack,"",@progbits Original __FD_ZERO, gcc -m64 .file "junk.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 pushq %rbx subq $32, %rsp movl $0, %eax movl $16, %edx leaq -160(%rbp), %rbx .cfi_offset 3, -24 movq %rdx, %rcx movq %rbx, %rdi #APP # 45 "junk.c" 1 cld; rep; stosq # 0 "" 2 #NO_APP movl %edi, %eax movl %ecx, %edx movl %edx, -24(%rbp) movl %eax, -20(%rbp) movl $0, %eax addq $32, %rsp popq %rbx leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)" .section .note.GNU-stack,"",@progbits (The subtle flaw I see is due to the use of int __d1 for an address on an x86_64 machine. The completely useless and benign store into __d1 is always a movl, even on an x86_64 machine. That is not technically correct. __d1 should really be declared void * __d1.) Here is the assembly output for gcc -m32 and gcc -m64 using the replacement __FD_ZERO asm: Replacement __FD_ZERO, gcc -m32 .file "junk.c" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp pushl %edi pushl %ebx addl $-128, %esp movl $0, %eax movl $32, %edx leal -136(%ebp), %ebx movl %edx, %ecx movl %ebx, %edi #APP # 45 "junk.c" 1 cld; rep; stosl # 0 "" 2 #NO_APP movl $0, %eax subl $-128, %esp popl %ebx popl %edi popl %ebp ret .size main, .-main .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)" .section .note.GNU-stack,"",@progbits Replacement __FD_ZERO, gcc -m64 .file "junk.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 pushq %rbx subq $16, %rsp movl $0, %eax movl $16, %edx leaq -144(%rbp), %rbx .cfi_offset 3, -24 movq %rdx, %rcx movq %rbx, %rdi #APP # 45 "junk.c" 1 cld; rep; stosq # 0 "" 2 #NO_APP movl $0, %eax addq $16, %rsp popq %rbx leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)" .section .note.GNU-stack,"",@progbits The code is a little tighter: there is no allocation for __d0 and __d1 on the stack, and the stores to __d0 and __d1 are of course also gone, since they no longer exist. What I do not know is how to tell the compiler that the instruction clobbers %ecx and %edi as side-effects. I do not even know if that is necessary. I tried adding them to the clobber list, but then the asm would not compile (can't find a register in class ‘CREG’ while reloading ‘asm’). Someone more knowledgeable than I will have to say whether there are any loose ends that need to be cleaned up. I apologize if this is the wrong list to post this, and for being so long-winded. I tried to be accurate and complete. Please steer me elsewhere, if this post is inappropriate. Thank you, Larry Baker US Geological Survey