Hello, I discovered a failure relating to atomic NAND operation on x86 platform, which can be confirmed using the included test-case. The test was done with gcc 4.2.4, using 8-, 16-, 32- and 64-bit data width. Test cases on other logic atomic operators passes all width-size except NAND. I have read through the assembly code generated and confirm that some wrong codes are generated when no-optimization and -O.
I ) Test case : /* Compile using: gcc -c -march=i686 test.c To get assembly listing: gcc -S -march=i686 test.c To get mix c and assembly listing: gcc -c -g -Wa,-a,-ad -march=i686 test.c > test-xxx.lst */ #include <stddef.h> #include <stdlib.h> #include <stdio.h> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; typedef unsigned long long QWORD; int main(void) { WORD xLoc; /* change xLoc type to BYTE, WORD, DWORD, QWORD to test different data-width */ typeof(xLoc) xIn, xOut, xExpect, i = 1; xLoc = xIn = (typeof(xIn)) ~ (1<<i); xExpect = (typeof(xIn)) ~(xIn & ((typeof(xIn)) 0x7F)); /* Both __sync_nand_and_fetch and __sync_fetch_and_nand have the same problem */ xOut = __sync_nand_and_fetch(&xLoc, (typeof(xIn)) 0x7F); if (xOut!=xExpect) printf("__sync_nand_and_fetch():; wrong result; i(%d) xIn(%x) xExpect(%x) xOut(%x) xLoc(%x)\n", i, xIn, xExpect, xOut, xLoc); return 0; } II ) Output of gcc -v -save-temps gcc -o test_bug -v -save-temps -march=i686 test_nand_bug.c Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.2.4/configure --prefix=/opt/gcc-4.2.4 --host=i686-pc-linux-gnu --target=i686-pc-linux-gnu Thread model: posix gcc version 4.2.4 /opt/gcc-4.2.4/libexec/gcc/i686-pc-linux-gnu/4.2.4/cc1 -E -quiet -v test_nand_bug.c -march=i686 -fpch-preprocess -o test_nand_bug.i ignoring nonexistent directory "/opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /opt/gcc-4.2.4/include /opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4/include /usr/include End of search list. /opt/gcc-4.2.4/libexec/gcc/i686-pc-linux-gnu/4.2.4/cc1 -fpreprocessed test_nand_bug.i -quiet -dumpbase test_nand_bug.c -march=i686 -auxbase test_nand_bug -version -o test_nand_bug.s GNU C version 4.2.4 (i686-pc-linux-gnu) compiled by GNU C version 4.2.4. GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32052 Compiler executable checksum: 383821529167afc2e47a93836e3831a4 as -V -Qy -o test_nand_bug.o test_nand_bug.s GNU assembler version 2.13.90.0.18 (i386-redhat-linux) using BFD version 2.13.90.0.18 20030206 /opt/gcc-4.2.4/libexec/gcc/i686-pc-linux-gnu/4.2.4/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o test_bug /usr/lib/crt1.o /usr/lib/crti.o /opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4/crtbegin.o -L/opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4 -L/opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4/../../.. test_nand_bug.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /opt/gcc-4.2.4/lib/gcc/i686-pc-linux-gnu/4.2.4/crtend.o /usr/lib/crtn.o -- Summary: atomic NAND op generate wrong code; __sync_nand_and_fetch, __sync_fetch_and_nand Product: gcc Version: 4.2.4 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: kokseng at ieee dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37908