Bug 12817 - [SYSV] Altivec code generation error with many registers used
Summary: [SYSV] Altivec code generation error with many registers used
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.3.2
: P2 normal
Target Milestone: 3.3.6
Assignee: Alan Modra
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2003-10-28 20:42 UTC by John Whitney
Modified: 2004-12-01 12:37 UTC (History)
3 users (show)

See Also:
Host:
Target: powerpc-linux
Build:
Known to work: 3.4.4 3.3.6 4.0.0
Known to fail:
Last reconfirmed: 2003-11-18 07:28:48


Attachments
Test code demonstrating problem (144 bytes, text/plain)
2003-10-28 20:45 UTC, John Whitney
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Whitney 2003-10-28 20:42:27 UTC
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.
Comment 1 John Whitney 2003-10-28 20:45:35 UTC
Created attachment 5013 [details]
Test code demonstrating problem
Comment 2 Andrew Pinski 2003-10-30 05:03:32 UTC
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?).
Comment 3 Segher Boessenkool 2003-10-30 13:44:12 UTC
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?

Comment 4 Andrew Pinski 2003-11-18 07:28:48 UTC
Confirmed, I do not know why gcc saves them at all, note that on the mainline now gcc saves the 
altivec registers but right.
Comment 5 Jim Wilson 2003-11-21 06:29:11 UTC
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
Comment 6 Segher Boessenkool 2003-11-21 09:23:01 UTC
I don't think the actual bug of this report is solved.

Hard to check without a testcase, though ;-)
Comment 7 Andrew Pinski 2003-11-21 09:49:13 UTC
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.
Comment 8 Alan Modra 2004-11-26 09:54:48 UTC
/* 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;
}
Comment 10 GCC Commits 2004-12-01 05:48:00 UTC
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

Comment 11 GCC Commits 2004-12-01 05:54:27 UTC
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

Comment 12 GCC Commits 2004-12-01 06:13:40 UTC
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

Comment 13 Alan Modra 2004-12-01 06:21:24 UTC
Fixed on all active branches.