We are using GCC 3.2 for the PowerPC 74xx to compile the Linux Test Project code (in specific, the write04 test). I found that the resulting executable was segfaulting. Investigation showed the following assembly code: 70: 7d 80 42 a6 mfvrsave r12 74: 91 8c ff 20 stw r12,-224(r12) 78: 65 8c df ff oris r12,r12,57343 7c: 61 8c ff ff ori r12,r12,65535 80: 7d 80 43 a6 mtvrsave r12 VRSAVE was 0, so line 74 resulted in a NULL pointer access. I've come up with a much-reduced test program that exercises this problem: ------------------- #include <signal.h> #include <setjmp.h> #include <limits.h> static sigjmp_buf jmp; int main(int argc, char **argv) { char wbuf[8 * PIPE_BUF]; if (sigsetjmp(jmp, 1)) { return 1; } return 0; } ------------------- This produces the following assembly code: 10000490 <main>: 10000490: 7c 2c 0b 78 mr r12,r1 10000494: 3c 00 ff ff lis r0,-1 10000498: 60 00 7e 30 ori r0,r0,32304 1000049c: 7c 21 01 6e stwux r1,r1,r0 100004a0: 38 00 fe 50 li r0,-432 100004a4: 7e 8c 01 ce stvx v20,r12,r0 100004a8: 38 00 fe 60 li r0,-416 100004ac: 7e ac 01 ce stvx v21,r12,r0 100004b0: 38 00 fe 70 li r0,-400 100004b4: 7e cc 01 ce stvx v22,r12,r0 100004b8: 38 00 fe 80 li r0,-384 100004bc: 7e ec 01 ce stvx v23,r12,r0 100004c0: 38 00 fe 90 li r0,-368 100004c4: 7f 0c 01 ce stvx v24,r12,r0 100004c8: 38 00 fe a0 li r0,-352 100004cc: 7f 2c 01 ce stvx v25,r12,r0 100004d0: 38 00 fe b0 li r0,-336 100004d4: 7f 4c 01 ce stvx v26,r12,r0 100004d8: 38 00 fe c0 li r0,-320 100004dc: 7f 6c 01 ce stvx v27,r12,r0 100004e0: 38 00 fe d0 li r0,-304 100004e4: 7f 8c 01 ce stvx v28,r12,r0 100004e8: 38 00 fe e0 li r0,-288 100004ec: 7f ac 01 ce stvx v29,r12,r0 100004f0: 38 00 fe f0 li r0,-272 100004f4: 7f cc 01 ce stvx v30,r12,r0 100004f8: 38 00 ff 00 li r0,-256 100004fc: 7f ec 01 ce stvx v31,r12,r0 10000500: 7d 80 42 a6 mfvrsave r12 10000504: 91 8c ff 20 stw r12,-224(r12) 10000508: 65 8c df ff oris r12,r12,57343 1000050c: 61 8c ff ff ori r12,r12,65535 10000510: 7d 80 43 a6 mtvrsave r12 10000514: 7c 08 02 a6 mflr r0 Again, the zero-containing r12 is used at address 0x10000500. This appears to be caused by the 32k stack variable, wbuf. If that variable is made static, or reduced in size, r1 is used as expected in the line following mfvrsave, instead of the erroneous r12. This problem appears in GCC 3.2, and in a test build I made of GCC 3.3.2.
Created attachment 5013 [details] Test code demonstrating problem
On powerpc-apple-darwin in 3.3.2 (20030908), I get: mfspr r12,256 stw r12,-224(r1) oris r12,r12,0xdfff ori r12,r12,65535 mtspr 256,r12 which looks right. on the mainline, GCC does not even save the altivec registers at all (why?).
Subject: Re: Altivec code generation error with setjmp pinskia at gcc dot gnu dot org wrote: > On powerpc-apple-darwin in 3.3.2 (20030908), I get: > mfspr r12,256 > stw r12,-224(r1) > oris r12,r12,0xdfff > ori r12,r12,65535 > mtspr 256,r12 > which looks right. It does. > on the mainline, GCC does not even save the altivec registers at all (why?). Why should it save _any_ registers (that are not changed before the call to setjmp()? setjmp() will just save them again?
Confirmed, I do not know why gcc saves them at all, note that on the mainline now gcc saves the altivec registers but right.
Gcc no longer saves the FP or altivec registers. See PR 13133 and the patch I checked in for it in the message http://gcc.gnu.org/ml/gcc-patches/2003-11/msg01667.html
I don't think the actual bug of this report is solved. Hard to check without a testcase, though ;-)
Can still happen when you use all the altivec registers, segher is working on a fix for that bug and this is really a target bug.
/* vrsave code in the prologue trashes frame pointer reg -m32 -maltivec -mabi=altivec -mvrsave=yes -S pr12817.c */ #define vector __attribute__ ((vector_size (16))) extern void foo (int *); vector int v_add (vector int a, vector int b) { int x[10000]; foo (x); return a + b; }
http://gcc.gnu.org/ml/gcc-patches/2004-11/msg02247.html
Subject: Bug 12817 CVSROOT: /cvs/gcc Module name: gcc Changes by: amodra@gcc.gnu.org 2004-12-01 05:47:52 Modified files: gcc : ChangeLog gcc/config/rs6000: rs6000.c Log message: PR target/12817 * config/rs6000/rs6000.c (rs6000_emit_prologue): Use r0 for vrsave. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6657&r2=2.6658 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.c.diff?cvsroot=gcc&r1=1.758&r2=1.759
Subject: Bug 12817 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: amodra@gcc.gnu.org 2004-12-01 05:54:22 Modified files: gcc : ChangeLog gcc/config/rs6000: rs6000.c Log message: PR target/12817 * config/rs6000/rs6000.c (rs6000_emit_prologue): Use r0 for vrsave. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.710&r2=2.2326.2.711 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.576.2.36&r2=1.576.2.37
Subject: Bug 12817 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: amodra@gcc.gnu.org 2004-12-01 06:13:19 Modified files: gcc : ChangeLog gcc/config/rs6000: rs6000.c Log message: PR target/12817 * config/rs6000/rs6000.c (rs6000_emit_prologue): Use r0 for vrsave. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.1029&r2=1.16114.2.1030 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/rs6000/rs6000.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.403.2.15&r2=1.403.2.16
Fixed on all active branches.