This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/11018 (SPARC)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 30 May 2003 15:01:07 +0200
- Subject: [PATCH] Fix PR optimization/11018 (SPARC)
Hi,
This is a miscompilation of GNU tar 1.13.25 on 32-bit Ultrasparc at -O2, a
regression from GCC 3.2.3 present on 3.3 branch and latent on mainline.
There is a bogus test in the sparc_v8plus_shift function that is invoked when
emitting assembly: it tests for the presence of a SCRATCH, which has been
eliminated by the register allocation passes.
Bootstrapped/regtested on sparc-sun-solaris2.8 --with-cpu=ultrasparc
(c,c++,objc,f77 3.3 branch). Ok for mainline and 3.3 branch?
--
Eric Botcazou
2003-05-30 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/11018
* config/sparc/sparc.c (sparc_v8plus_shift): Use which_alternative
consistently to decide whether the scratch register is really required.
2003-05-30 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/ultrasparc9.c: New test.
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.233.4.2
diff -u -p -r1.233.4.2 sparc.c
--- config/sparc/sparc.c 15 May 2003 03:12:30 -0000 1.233.4.2
+++ config/sparc/sparc.c 29 May 2003 21:17:45 -0000
@@ -3393,7 +3393,7 @@ mem_min_alignment (mem, desired)
/* Vectors to keep interesting information about registers where it can easily
- be got. We use to use the actual mode value as the bit number, but there
+ be got. We used to use the actual mode value as the bit number, but there
are more than 32 modes now. Instead we use two tables: one indexed by
hard register number, and one indexed by mode. */
@@ -7971,6 +7971,8 @@ sparc_check_64 (x, insn)
return 0;
}
+/* Returns assembly code to perform a DImode shift using
+ a 64-bit global or out register on SPARC-V8+. */
char *
sparc_v8plus_shift (operands, insn, opcode)
rtx *operands;
@@ -7979,8 +7981,11 @@ sparc_v8plus_shift (operands, insn, opco
{
static char asm_code[60];
- if (GET_CODE (operands[3]) == SCRATCH)
+ /* The scratch register is only required when the destination
+ register is not a 64-bit global or out register. */
+ if (which_alternative != 2)
operands[3] = operands[0];
+
if (GET_CODE (operands[1]) == CONST_INT)
{
output_asm_insn ("mov\t%1, %3", operands);
@@ -7994,6 +7999,7 @@ sparc_v8plus_shift (operands, insn, opco
}
strcpy(asm_code, opcode);
+
if (which_alternative != 2)
return strcat (asm_code, "\t%0, %2, %L0\n\tsrlx\t%L0, 32, %H0");
else
/* PR optimization/11018 */
/* Originator: <partain@dcs.gla.ac.uk> */
/* { dg-do run { target sparc*-*-* } } */
/* { dg-options "-O2 -mcpu=ultrasparc" } */
/* This used to fail on 32-bit Ultrasparc because
of broken DImode shift patterns. */
extern void abort(void);
typedef unsigned long long uint64_t;
typedef unsigned int size_t;
void to_octal (uint64_t value, char *where, size_t size)
{
uint64_t v = value;
size_t i = size;
do
{
where[--i] = '0' + (v & ((1 << 3) - 1));
v >>= 3;
}
while (i);
}
int main (void)
{
char buf[8];
to_octal(010644, buf, 6);
if (buf[1] != '1')
abort();
return 0;
}