GCC reuses stack slot in setjmp-calling function -- is it a bug or feature?
Hi, Minimal reproduction for x86: #include #include #include jmp_buf something_happened; int key_gdata = 2; int store_data; void __attribute__((noinline)) initiate(void) { longjmp(something_happened, 1); } int __attribute__ ((noinline)) foo(int x) { return x + 1; } int __attribute__((noinline)) amibuggy(int x, int y1, int y2, int y3) { int nextdata, idx, key_data; key_data = key_gdata; if (setjmp(something_happened)) { if (key_data != key_gdata) { fprintf(stderr, "Test failed: data = %d, g_data = %d\n", key_data, key_gdata); abort(); } else { fprintf(stdout, "Test passed\n"); fprintf(stdout, "data = %d, g_data = %d\n", key_data, key_gdata); return 0; } } store_data = key_data; nextdata = key_gdata; idx = foo(nextdata); for (;idx != 0; --idx) { int tmp = store_data; nextdata += foo(tmp); store_data = foo(nextdata); } initiate(); return 0; } int main(void) { amibuggy(9, 5, 16, 36); amibuggy(0, 0, 0, 0); return 0; } Compile with gcc-4.7.2 with line: gcc -O2 repro.c -o repro.x86 Now run and you will see test "magically" failed. What happens? Compiler on register allocation pass decided to reuse stack slot 12(%rsp) where key_data persisted. movl key_gdata(%rip), %eax movl %eax, 12(%rsp) call _setjmp ... and later ... .L10: movl 12(%rsp), %edi <--- oops! call foo setjmp stored stack pointer, next frame slot is overwritten by spill/fill (because compiler thinks that key_data is already dead at this point. Then everything explodes. I am not sure that it is a bug, but situation is rather complicated for programmer -- I think in this case programmer really may rely on context restoring after longjmp, and surprise is really great. Question to gcc-help: Please comment on should I file this in bugzilla, or should I live with it. Question to gcc: Really I found this problem in private backend and want to fix it for my users, no matter first answer is yes or no. Maybe somehow restrict stack slot reusage if function calls setjmp. But I am not so good in reload internals. Any advices about how to locally fix it in private backend sources (I haven't still done any changes to normal gcc-4.7.2, just added new machine description) are very appreciated. --- With best regards, Konstantin
Re: GCC reuses stack slot in setjmp-calling function -- is it a bug or feature?
Konstantin Vladimirov writes: > Hi, > > Minimal reproduction for x86: > > #include > #include > #include > > jmp_buf something_happened; > int key_gdata = 2; > > int store_data; > > void __attribute__((noinline)) > initiate(void) > { > longjmp(something_happened, 1); > } > > int __attribute__ ((noinline)) > foo(int x) > { > return x + 1; > } > > int __attribute__((noinline)) > amibuggy(int x, int y1, int y2, int y3) > { > int nextdata, idx, key_data; > > key_data = key_gdata; > > if (setjmp(something_happened)) > { > if (key_data != key_gdata) > { > fprintf(stderr, "Test failed: data = %d, g_data = %d\n", > key_data, key_gdata); > abort(); > } > else > { > fprintf(stdout, "Test passed\n"); > fprintf(stdout, "data = %d, g_data = %d\n", key_data, key_gdata); > return 0; > } > } > > store_data = key_data; > nextdata = key_gdata; > > idx = foo(nextdata); > > for (;idx != 0; --idx) > { > int tmp = store_data; > nextdata += foo(tmp); > store_data = foo(nextdata); > } > > initiate(); > return 0; > } > > int > main(void) > { > amibuggy(9, 5, 16, 36); > amibuggy(0, 0, 0, 0); > return 0; > } > > > Compile with gcc-4.7.2 with line: > > gcc -O2 repro.c -o repro.x86 > > Now run and you will see test "magically" failed. > > What happens? Compiler on register allocation pass decided to reuse > stack slot 12(%rsp) where key_data persisted. > > movl key_gdata(%rip), %eax > movl %eax, 12(%rsp) > call _setjmp > > ... and later ... > > .L10: > movl 12(%rsp), %edi <--- oops! > call foo > > setjmp stored stack pointer, next frame slot is overwritten by > spill/fill (because compiler thinks that key_data is already dead at > this point. Then everything explodes. > > I am not sure that it is a bug, but situation is rather complicated > for programmer -- I think in this case programmer really may rely on > context restoring after longjmp, and surprise is really great. > > Question to gcc-help: Please comment on should I file this in > bugzilla, or should I live with it. > > Question to gcc: Really I found this problem in private backend and > want to fix it for my users, no matter first answer is yes or no. > Maybe somehow restrict stack slot reusage if function calls setjmp. > But I am not so good in reload internals. Any advices about how to > locally fix it in private backend sources (I haven't still done any > changes to normal gcc-4.7.2, just added new machine description) are > very appreciated. You need to read the C standard and understand the restrictions it places on the values of non-volatile automatic variables when setjmp returns due to a longjmp. Look for "The longjmp function" in WG14/n1124.pdf or n1494.pdf. Then you'll need to use "volatile" or restructure your code slightly.
Failure building current snapshot [Cygwin]
The current snapshot [*] fails to build on Cygwin as follow: [...] /work/gcc-4.9-20130414/Work/./gcc/xgcc -B/work/gcc-4.9-20130414/Work/./gcc/ -B/usr/local/gfortran/i686-pc-cygwin/bin/ -B/usr/local/gfortran/i686-pc-cygwin/lib/ -isystem /usr/local/gfortran/i686-pc-cygwin/include -isystem /usr/local/gfortran/i686-pc-cygwin/sys-include-g -O2 -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -I. -I. -I../.././gcc -I/work/gcc-4.9-20130414/libgcc -I/work/gcc-4.9-20130414/libgcc/. -I/work/gcc-4.9-20130414/libgcc/../gcc -I/work/gcc-4.9-20130414/libgcc/../include -I/work/gcc-4.9-20130414/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -g0 -finhibit-size-directive -fno-inline -fno-exceptions -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize -fno-stack-protector -I. -I. -I../.././gcc -I/work/gcc-4.9-20130414/libgcc -I/work/gcc-4.9-20130414/libgcc/. -I/work/gcc-4.9-20130414/libgcc/../gcc -I/work/gcc-4.9-20130414/libgcc/../include -I/work/gcc-4.9-20130414/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -o crtbegin.o -MT crtbegin.o -MD -MP -MF crtbegin.dep -fno-omit-frame-pointer -c /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c /work/gcc-4.9-20130414/Work/./gcc/xgcc -B/work/gcc-4.9-20130414/Work/./gcc/ -B/usr/local/gfortran/i686-pc-cygwin/bin/ -B/usr/local/gfortran/i686-pc-cygwin/lib/ -isystem /usr/local/gfortran/i686-pc-cygwin/include -isystem /usr/local/gfortran/i686-pc-cygwin/sys-include-g -O2 -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -I. -I. -I../.././gcc -I/work/gcc-4.9-20130414/libgcc -I/work/gcc-4.9-20130414/libgcc/. -I/work/gcc-4.9-20130414/libgcc/../gcc -I/work/gcc-4.9-20130414/libgcc/../include -I/work/gcc-4.9-20130414/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -g0 -finhibit-size-directive -fno-inline -fno-exceptions -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize -fno-stack-protector -I. -I. -I../.././gcc -I/work/gcc-4.9-20130414/libgcc -I/work/gcc-4.9-20130414/libgcc/. -I/work/gcc-4.9-20130414/libgcc/../gcc -I/work/gcc-4.9-20130414/libgcc/../include -I/work/gcc-4.9-20130414/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -o crtend.o -MT crtend.o -MD -MP -MF crtend.dep -fno-omit-frame-pointer -Wno-error -c /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtend.c /work/gcc-4.9-20130414/Work/./gcc/xgcc -B/work/gcc-4.9-20130414/Work/./gcc/ -B/usr/local/gfortran/i686-pc-cygwin/bin/ -B/usr/local/gfortran/i686-pc-cygwin/lib/ -isystem /usr/local/gfortran/i686-pc-cygwin/include -isystem /usr/local/gfortran/i686-pc-cygwin/sys-include-g -O2 -O2 -I/work/gcc-4.9-20130414/libgcc/../winsup/w32api/include -I/work/gcc-4.9-20130414/libgcc/../winsup/include -I/work/gcc-4.9-20130414/libgcc/../winsup/cygwin/include -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include-g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -I. -I. -I../.././gcc -I/work/gcc-4.9-20130414/libgcc -I/work/gcc-4.9-20130414/libgcc/. -I/work/gcc-4.9-20130414/libgcc/../gcc -I/work/gcc-4.9-20130414/libgcc/../include -I/work/gcc-4.9-20130414/libgcc/config/libbid -DENABLE_DECIMAL_BID_FORMAT -DHAVE_CC_TLS -DUSE_EMUTLS -o crtfastmath.o -MT crtfastmath.o -MD -MP -MF crtfastmath.dep -mfxsr -msse -c /work/gcc-4.9-20130414/libgcc/config/i386/crtfastmath.c echo > _chkstk.vis echo > _chkstk_ms.vis rm -f libgcov.a /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtend.c:67:1: warning: constructor priorities from 0 to 100 are reserved for the implementation [enabled by default] static void register_frame_ctor (void) __attribute__ ((constructor (0))); ^ /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtend.c:82:1: warning: destructor priorities from 0 to 100 are reserved for the implementation [enabled by default] static void deregister_frame_dtor (void) __attribute__ ((destructor (0))); ^ objects="_gcov.o _gcov_merge_add.o _gcov_merge_single.o _gcov_merge_delta.o _gcov_fork.o _gcov_execl.o _gcov_execlp.o _gcov_execle.o _gcov_execv.o _gcov_execvp.o _gcov_execve.o _gcov_reset.o _gcov_dump.o _gcov_interval_profiler.o _gcov_pow2_profiler.o _gcov_one_value_profiler.o _gcov_indirect_call_profiler.o _gcov_average_profiler.o _gcov_ior_profiler.o _gcov_merge_ior.o"; \ if test -z "$objects"; then \ echo 'int __libgcc_eh_dummy;' > eh_dummy.c;\ /work/gcc-4.9-20130414/Work/./gcc/xgcc -B/work/gcc-4.9-20130414/Work/./gcc/ -B/usr/local/gfortran/i686-pc-cygwin/bin/ -B/usr/local/gfortran/i686-pc-cygwin/lib/ -isystem /usr/local/gfortran/i686-pc-cygwin/include -isystem /usr/local/gfortran/i686-pc-cygwin/sys-include-g -O2 -O2 -I/work/gcc-4.9-20130414/libgcc/../wins
an idea about GSOC 2013
Hi all: I'm a student from Peking University, China. Recently i study the loop parallel on multicore computer. And i also find that this year's GCC GSOC has the tasks about the loop unrolling. So i want to find out if i can do something to improve the loop proformance on gcc. i hope to discuss this problem with you and find out something to do. Looking forword to your reply. Thank you. Ziqian
Power/Energy Awareness in GCC
Hi, Does GCC currently have any power/energy reduction optimizations or any performance optimizations that take power/energy consumption into account? We are currently working on a research project on instruction scheduling for low power (experimenting with different algorithms for minimizing switching power) and would like to find out if GCC already has such a scheduler and how it can be enabled, so that we can experiment with it. Regards Ghassan Shobaki, PH.D Assistant Professor Department of Computer Science Princess Sumaya University for Technology Amman, Jordan
Re: Power/Energy Awareness in GCC
Ghassan Shobaki wrote: We are currently working on a research project on instruction scheduling for low power (experimenting with different algorithms for minimizing switching power) and would like to find out if GCC already has such a scheduler and how it can be enabled, so that we can experiment with it. Your project sounds similar to the following project: http://gcc.gnu.org/ml/gcc/2013-03/msg00259.html ("Identifying Compiler Options to Minimise Energy Consumption for Embedded Platforms"). Tobias
Re: Failure building current snapshot [Cygwin]
On 15/04/2013 15:50, Angelo Graziosi wrote: > The current snapshot [*] fails to build on Cygwin as follow: > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c: In > function ‘__gcc_register_frame’: > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:106:19: > warning: array subscript is above array bounds [-Warray-bounds] >if (__JCR_LIST__[0]) >^ > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:120:1: > error: unrecognizable insn: > } > ^ > (insn 15 14 16 5 (set (reg:SI 63) > (symbol_ref:SI ("GetModuleHandleA@4") [flags 0x441] > )) > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:109 -1 > (nil)) > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:120:1: > internal compiler error: in extract_insn, at recog.c:2150 > > /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:120:1: > internal compiler error: Aborted > xgcc: internal compiler error: Aborted (program cc1) > Please submit a full bug report, > with preprocessed source if appropriate. Had a report similar to this offlist last week, suggested it was fallout from Kai's 64-bit patches. Trying to repro now, please file a PR and CC me and Kai. cheers, DaveK
Re: Power/Energy Awareness in GCC
On 15.04.2013 20:21, Tobias Burnus wrote: Ghassan Shobaki wrote: We are currently working on a research project on instruction scheduling for low power (experimenting with different algorithms for minimizing switching power) and would like to find out if GCC already has such a scheduler and how it can be enabled, so that we can experiment with it. Your project sounds similar to the following project: http://gcc.gnu.org/ml/gcc/2013-03/msg00259.html ("Identifying Compiler Options to Minimise Energy Consumption for Embedded Platforms"). We also did similar research in the past, mainly investigating how compiler feedback (via instrumentation and profiling) can assist dynamic voltage scaling in the OS (we had fully offline DVS as well as the patches to the Linux scheduler), but we also did some experiments with controlling bit-switching in the scheduler and some other work. You can find the relevant papers with some preliminary DVS work and bit-switching experiments at http://www.doc.ic.ac.uk/~phjk/GROW09/papers/06-PowerBelevantsev.pdf and with more DVS research and experiments from GROW 2010 at http://gcc.gnu.org/wiki/GROW-2010?action=AttachFile&do=get&target=2010-GROW-Proceedings.pdf. To be honest, I can only repeat the same things I said to James on the 2012 Cauldron -- I don't think you can achieve much of power savings from within the compiler, at least until the hardware design will change. The scheduling freedom in minimizing bit-switching is very limited and this is not going to buy much. Any information that a compiler can produce for you will be about program behavior related to CPU and memory, and no matter how well you use it, again you will not save much power as nowadays CPU will not be the largest power consumer in an embedded system (if you save e.g. 10% CPU power consumption which is 10% of total system consumption, that's only 1%). One can achieve more by turning off a display or a networking device. But I will be happy to be proven wrong :-) So good luck with the research. Andrey
Re: Failure building current snapshot [Cygwin]
On 16/04/2013 07:05, Dave Korn wrote: > On 15/04/2013 15:50, Angelo Graziosi wrote: >> /work/gcc-4.9-20130414/libgcc/config/i386/cygming-crtbegin.c:120:1: >> error: unrecognizable insn: >> } >> ^ >> (insn 15 14 16 5 (set (reg:SI 63) >> (symbol_ref:SI ("GetModuleHandleA@4") [flags 0x441] >> )) ix86_legitimate_address_p fails on (symbol_ref:SI ("GetModuleHandleA@4") [flags 0x441] ). I suspect that isn't helpful. cheers, DaveK