http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60998
Bug ID: 60998 Summary: [MIPS] -O3 produces infinite while() loop. -O2 produces correct code. Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: exmortis at yandex dot ru 1. The compiler toolchain was downloaded from CodeSourcer site: http://sourcery.mentor.com/public/gnu_toolchain/mips-linux-gnu/mips-2013.11 -36-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2 2. Unpacked to the home dir: tar jxf mips-2013.11-36-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2 3. Version checking: chibisov@lazar:~$ ./mips-2013.11/bin/mips-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=./mips-2013.11/bin/mips-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/chibisov/mips-2013.11/bin/../libexec/gcc/mips-linu x-gnu/4.8.1/lto-wrapper Target: mips-linux-gnu Configured with: /scratch/cmoore/fall2013-linux-final/src/gcc-4.8-2013.11/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=mips-linux-gnu --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-arch-32=mips32r2 --with-arch-64=mips64r2 --with-float=hard --with-mips-plt --enable-extra-sgxxlite-multilibs --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} -D__CS_SOURCERYGXX_MAJ__=2013 -D__CS_SOURCERYGXX_MIN__=11 -D__CS_SOURCERYGXX_REV__=36' --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery CodeBench Lite 2013.11-36' --with-bugurl=https://sourcery.mentor.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/mips-linux-gnu/libc --with-build-sysroot=/scratch/cmoore/fall2013-linux-final/install/opt/codeso urcery/mips-linux-gnu/libc --with-gmp=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-linu x-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-lin ux-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-linu x-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-linu x-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/usr --with-cloog=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-li nux-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/us r --with-libelf=/scratch/cmoore/fall2013-linux-final/obj/pkg-2013.11-36-mips-l inux-gnu/mips-2013.11-36-mips-linux-gnu.extras/host-libs-i686-pc-linux-gnu/u sr --enable-libgomp --disable-libitm --disable-libssp --enable-poison-system-directories --with-build-time-tools=/scratch/cmoore/fall2013-linux-final/install/opt/cod esourcery/mips-linux-gnu/bin --with-build-time-tools=/scratch/cmoore/fall2013-linux-final/install/opt/cod esourcery/mips-linux-gnu/bin SED=sed Thread model: posix gcc version 4.8.1 (Sourcery CodeBench Lite 2013.11-36) chibisov@lazar:~$ 4. Minimal test file t.c: void *memset(void *s, int c, int count) { if (count) { char *d = s; do { *d++ = c; } while (--count); } return s; } 5. The compiler is run with recommended keys ("Reporting Bugs" from http://gcc.gnu.org/bugs/#detailed) chibisov@lazar:~$ ./mips-2013.11/bin/mips-linux-gnu-gcc -Wall -Wextra -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations --save-temps -O3 -c t.c chibisov@lazar:~$ No warnings or errors are shown. 6. The contents of t.i is the following: # 1 "t.c" # 1 "<command-line>" # 1 "/home/chibisov/mips-2013.11/mips-linux-gnu/libc/usr/include/stdc-predef.h" 1 3 4 # 30 "/home/chibisov/mips-2013.11/mips-linux-gnu/libc/usr/include/stdc-predef.h" 3 4 # 1 "/home/chibisov/mips-2013.11/mips-linux-gnu/libc/usr/include/bits/predefs.h" 1 3 4 # 31 "/home/chibisov/mips-2013.11/mips-linux-gnu/libc/usr/include/stdc-predef.h" 2 3 4 # 1 "<command-line>" 2 # 1 "t.c" void *memset(void *s, int c, int count) { if (count) { char *d = s; do { *d++ = c; } while (--count); } return s; } 7. The contents of t.s is the following: .file 1 "t.c" .section .mdebug.abi32 .previous .nan legacy .gnu_attribute 4, 1 .abicalls .option pic0 # -G value = 0, Arch = mips32r2, ISA = 33 # GNU C (Sourcery CodeBench Lite 2013.11-36) version 4.8.1 (mips-linux-gnu) # compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.1-p2, MPC version 1.0.1 # GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 # options passed: -fpreprocessed t.i -meb -march=mips32r2 -mhard-float # -mllsc -mplt -mno-shared -mabi=32 -O3 -Wall -Wextra -fno-strict-aliasing # -fwrapv -fno-aggressive-loop-optimizations -fverbose-asm # options enabled: -fauto-inc-dec -fbranch-count-reg -fcaller-saves # -fcombine-stack-adjustments -fcommon -fcompare-elim -fcprop-registers # -fcrossjumping -fcse-follow-jumps -fdefer-pop -fdelayed-branch # -fdelete-null-pointer-checks -fdevirtualize -fdwarf2-cfi-asm # -fearly-inlining -feliminate-unused-debug-types # -fexpensive-optimizations -fforward-propagate -ffunction-cse -fgcse # -fgcse-after-reload -fgcse-lm -fgnu-runtime -fguess-branch-probability # -fhoist-adjacent-loads -fident -fif-conversion -fif-conversion2 # -findirect-inlining -finline -finline-atomics -finline-functions # -finline-functions-called-once -finline-small-functions -fipa-cp # -fipa-cp-clone -fipa-profile -fipa-pure-const -fipa-reference -fipa-sra # -fira-hoist-pressure -fira-share-save-slots -fira-share-spill-slots # -fivopts -fkeep-static-consts -fleading-underscore -fmath-errno # -fmerge-constants -fmerge-debug-strings -fmove-loop-invariants # -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls # -foptimize-strlen -fpartial-inlining -fpcc-struct-return -fpeephole # -fpeephole2 -fpredictive-commoning -fprefetch-loop-arrays -fregmove # -freorder-blocks -freorder-functions -frerun-cse-after-loop # -fsched-critical-path-heuristic -fsched-dep-count-heuristic # -fsched-group-heuristic -fsched-interblock -fsched-last-insn-heuristic # -fsched-rank-heuristic -fsched-spec -fsched-spec-insn-heuristic # -fsched-stalled-insns-dep -fschedule-insns -fschedule-insns2 # -fshow-column -fshrink-wrap -fsigned-zeros -fsplit-ivs-in-unroller # -fsplit-wide-types -fstrict-overflow -fstrict-volatile-bitfields # -fsync-libcalls -fthread-jumps -ftoplevel-reorder -ftrapping-math # -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch # -ftree-coalesce-vars -ftree-copy-prop -ftree-copyrename -ftree-cselim # -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre # -ftree-loop-distribute-patterns -ftree-loop-if-convert -ftree-loop-im # -ftree-loop-ivcanon -ftree-loop-optimize -ftree-parallelize-loops= # -ftree-partial-pre -ftree-phiprop -ftree-pre -ftree-pta -ftree-reassoc # -ftree-scev-cprop -ftree-sink -ftree-slp-vectorize -ftree-slsr # -ftree-sra -ftree-switch-conversion -ftree-tail-merge -ftree-ter # -ftree-vect-loop-version -ftree-vectorize -ftree-vrp -funit-at-a-time # -funswitch-loops -fuse-caller-save -fvect-cost-model -fverbose-asm # -fwrapv -fzero-initialized-in-bss -mabicalls -mcheck-zero-division # -mdivide-traps -mdouble-float -meb -mexplicit-relocs -mextern-sdata # -mfp-exceptions -mfp32 -mfused-madd -mglibc -mgp32 -mgpopt -mhard-float # -mimadd -mllsc -mlocal-sdata -mlong32 -mno-mdmx -mno-mips16 -mno-mips3d # -mplt -mrelax-pic-calls -msplit-addresses -mvr4130-align .text .align 2 .globl memset .set nomips16 .set nomicromips .ent memset .type memset, @function memset: .frame $sp,32,$31 # vars= 0, regs= 2/0, args= 16, gp= 8 .mask 0x80010000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-32 #,, sw $16,24($sp) #, sw $31,28($sp) #, beq $6,$0,$L4 #, count,, move $16,$4 # s, s jal memset # seb $5,$5 #, c $L4: lw $31,28($sp) #, move $2,$16 #, s lw $16,24($sp) #, j $31 # addiu $sp,$sp,32 #,, .set macro .set reorder .end memset .size memset, .-memset .ident "GCC: (Sourcery CodeBench Lite 2013.11-36) 4.8.1" 8. The disassembly listing of t.o: chibisov@lazar:~$ ./mips-2013.11/bin/mips-linux-gnu-objdump -d t.o t.o: file format elf32-tradbigmips Disassembly of section .text: 00000000 <memset>: 0: 27bdffe0 addiu sp,sp,-32 4: afb00018 sw s0,24(sp) 8: afbf001c sw ra,28(sp) c: 10c00003 beqz a2,1c <memset+0x1c> 10: 00808021 move s0,a0 14: 0c000000 jal 0 <memset> 18: 7c052c20 seb a1,a1 1c: 8fbf001c lw ra,28(sp) 20: 02001021 move v0,s0 24: 8fb00018 lw s0,24(sp) 28: 03e00008 jr ra 2c: 27bd0020 addiu sp,sp,32 chibisov@lazar:~$ The error is at offset 0x14 - jmp to beginning of the function memset: jal 0 <memset> 9. If "nop" is placed inside the loop, the generated code magically becomes correct: The contents of t.c: void *memset(void *s,int c,size_t count) { if (count) { char *d = s; do { *d++ = c; __asm__ __volatile__ (".word 0x25\n" : : ); } while (--count); } return s; } Disassembly of t.o: 00000000 <memset>: 0: 10c00009 beqz a2,28 <memset+0x28> 4: 00801021 move v0,a0 8: 30a500ff andi a1,a1,0xff c: 00863021 addu a2,a0,a2 10: 00801821 move v1,a0 14: 24630001 addiu v1,v1,1 18: a065ffff sb a1,-1(v1) 1c: 00000025 move zero,zero 20: 1466fffd bne v1,a2,18 <memset+0x18> 24: 24630001 addiu v1,v1,1 28: 03e00008 jr ra 2c: 00000000 nop 10. If t.c is compiled with -O2 the generated code is correct: chibisov@lazar:~$ ./mips-2013.11/bin/mips-linux-gnu-gcc -Wall -Wextra -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations --save-temps -O2 -c t.c chibisov@lazar:~$ ./mips-2013.11/bin/mips-linux-gnu-objdump -d t.o t.o: file format elf32-tradbigmips Disassembly of section .text: 00000000 <memset>: 0: 10c00007 beqz a2,20 <memset+0x20> 4: 00801021 move v0,a0 8: 7c052c20 seb a1,a1 c: 00863021 addu a2,a0,a2 10: 00801821 move v1,a0 14: 24630001 addiu v1,v1,1 18: 1466fffe bne v1,a2,14 <memset+0x14> 1c: a065ffff sb a1,-1(v1) 20: 03e00008 jr ra 24: 00000000 nop