Subject: toolchain/18286: compiler bug, probably in register renumbering
To: None <>
From: None <>
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
>Originator:     Lloyd Parkes
>Release:        NetBSD 1.6
Must Have Coffee
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 1.6 NetBSD 1.6 (GENERIC) #1: Thu Sep 12 21:20:11 NZST 2002 sparc64
Architecture: sparc64
Machine: sparc64

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.


Compile the following code with 'gcc -O2 -S' and look at the assembly
code. Alternatively try compiling and running MG 1.2.1 from 

==== Sample Code Start ====

#include <stdio.h>

typedef unsigned long u_long;
typedef unsigned char u_char;


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;

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;

typedef struct comp_frags_header
    huff_data hd;
    u_long uncompressed_size;
    u_long huff_words_size[MAX_HUFFCODE_LEN + 1];
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;

typedef struct dict_hash_table
    u_long size;
    huff_data *hd;
    u_long *codes;
    u_char **words;
    u_char **table[1];

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);

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;
      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;
	FatalError (1, "Bad dictionary kind\n");

  return (0);

  fclose (dict);
  return (1);
==== Sample Code End ====