Subject: toolchain/18286: compiler bug, probably in register renumbering
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lloyd@must-have-coffee.gen.nz>
List: netbsd-bugs
Date: 09/14/2002 20:12:02
>Number: 18286
>Category: toolchain
>Synopsis: compiler bug, probably in register renumbering
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: toolchain-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Sep 14 01:13:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Lloyd Parkes
>Release: NetBSD 1.6
>Organization:
Must Have Coffee
>Environment:
gcc version 2.95.3 20010315 (release) (NetBSD nb3)
GNU C version 2.95.3 20010315 (release) (NetBSD nb3) (sparc64-netbsd) compiled by GNU C version 2.95.3 20010315 (release) (NetBSD nb3).
System: NetBSD archangel.must-have-coffee.gen.nz 1.6 NetBSD 1.6 (GENERIC) #1: Thu Sep 12 21:20:11 NZST 2002 lloyd@archangel.must-have-coffee.gen.nz:/usr/obj/sys/arch/sparc64/compile/GENERIC sparc64
Architecture: sparc64
Machine: sparc64
>Description:
For the second parameter to the second call to Read_cfh in the example
code, -O works, but -O2 doesn't. With -O2 it seems that the registers
%l5 and %o1 are both renumbered to %o2 with unfortunate
consequences. The assembly code fragments are:
-O2 (bad) -O1 (good)
~~~~~~~~~ ~~~~~~~~~~
sethi %lm(cfh), %o2 sethi %lm(cfh), %l5
...
sethi %hh(cfh), %o1
ldx [%fp+2015], %o4
or %o2, %hm(cfh), %o2 or %o1, %hm(cfh), %o1
mov %l2, %o0
sllx %o2, 32, %o2 sllx %o1, 32, %o1
add %o2, %o2, %o2 add %o1, %l5, %o1
or %o2, %lo(cfh), %o2 or %o1, %lo(cfh), %o1
add %o4, %o2, %o1
With -O2 we end up getting the 64 bit constant that is being loaded
into %o1 horribly mangled.
>How-To-Repeat:
Compile the following code with 'gcc -O2 -S' and look at the assembly
code. Alternatively try compiling and running MG 1.2.1 from
http://www.cs.mu.oz.au/mg/mg-1.2.1.tar.gz.
==== Sample Code Start ====
#include <stdio.h>
typedef unsigned long u_long;
typedef unsigned char u_char;
#define MAX_HUFFCODE_LEN 31
typedef struct huff_data
{
int num_codes;
int mincodelen;
int maxcodelen;
int lencount[MAX_HUFFCODE_LEN + 1];
unsigned long min_code[MAX_HUFFCODE_LEN + 1];
char *clens;
}
huff_data;
unsigned long *Generate_Huffman_Codes (huff_data * data, u_long * mem);
typedef struct compression_dict_header
{
u_long dict_type;
u_long novel_method;
u_long params[15];
u_long num_words[2];
u_long num_word_chars[2];
u_long lookback;
}
compression_dict_header;
typedef struct comp_frags_header
{
huff_data hd;
u_long uncompressed_size;
u_long huff_words_size[MAX_HUFFCODE_LEN + 1];
}
comp_frags_header;
typedef struct compressed_text_header
{
u_long num_of_docs;
u_long num_of_words; /* number of words in collection */
u_long length_of_longest_doc; /* (characters) */
u_long padding1; /* padding to 8-byte multiple */
double ratio;
unsigned long long num_of_bytes;
}
compressed_text_header;
typedef struct dict_hash_table
{
u_long size;
huff_data *hd;
u_long *codes;
u_char **words;
u_char **table[1];
}
dict_hash_table;
static char *RCSID = "$Id: comp_dict.c,v 1.3 1994/10/20 03:56:41 tes Exp $";
compression_dict_header cdh;
compressed_text_header cth;
comp_frags_header cfh[2];
dict_hash_table *ht[2];
huff_data char_huff[2];
huff_data lens_huff[2];
u_long *char_codes[2], *lens_codes[2];
u_long Words_disk = 0;
dict_hash_table *
ReadInWords (FILE * dict, comp_frags_header * cfh,
int esc);
int
LoadCompressionDictionary (char *dict_file_name)
{
FILE *dict;
int which;
dict = fopen (dict_file_name, "r");
Words_disk = sizeof (u_long);
for (which = 0; which < 2; which++)
switch (cdh.dict_type)
{
case 5:
{
if (cdh.num_words[which])
{
if (Read_cfh (dict, &cfh[which], NULL, &Words_disk) == -1)
goto error;
if (!(ht[which] = ReadInWords (dict, &cfh[which], 1)))
goto error;
}
}
break;
case 6:
{
if (cdh.num_words[which])
{
if (Read_cfh (dict, &cfh[which], NULL, &Words_disk) == -1)
goto error;
}
if (!(char_codes[which] =
Generate_Huffman_Codes (&char_huff[which], NULL)))
goto error;
if (!(lens_codes[which] =
Generate_Huffman_Codes (&lens_huff[which], NULL)))
goto error;
}
break;
default:
FatalError (1, "Bad dictionary kind\n");
}
return (0);
error:
fclose (dict);
return (1);
}
==== Sample Code End ====
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: