[gnu.gcc.bug] Optimizer removes needed test

kent@SUNDC.EAST.SUN.COM (Kent Hauser) (09/16/89)

Configuration: gcc 1.35, Sun-3, sunos 3.5

For the following file, the test for the `if' statement shown
is deleted when optimizing.  The assembled code is also attached.
The command used is `gcc -O -g -S test.c'

	Kent Hauser
	kent@tfd.uucp,
	{sun!sundc, uunet}!tfd!kent

---------test.c-------------

#define MANT_SIZE 4		/* number of 16-bit elements in mantissa */
#define MAX_EXPONENT	0x10000	/* this value causes over/under flow */

typedef struct real {
    unsigned short  mant[MANT_SIZE];
    int             exponent;
    unsigned        sign:1;
    unsigned        zero:1;
    unsigned        overflow:1;
    unsigned        nan:1;
}               REAL;

REAL           *
fp_round (fp, bits)
    struct real    *fp;
{
    int             words = bits / 16;

    int             mask = 1 << (15 - bits % 16);

    if (fp->mant[words] & mask) {
	do {
	    mask += fp->mant[words];
	    fp->mant[words] = mask;
	    mask >>= 16;
	} while (words--);
	if (mask) {	/* Gcc bug: test omitted */
	    fp_lshift (fp, 1);
	    fp->mant[0] |= 0x8000;
	    fp->exponent++;
	}
    }
    return fp;
}


-------------test.lst------------------

                                    	#NO_APP
00000000'                               	gcc_compiled.:
00000000'                               	Ltext:
00000000'                               	.text
00000000'                               		.even
00000000'                               	.globl _fp_round
00000000'                               	_fp_round:
|     1			
|     2			#define MANT_SIZE 4		/* number of 16-bit elements in mantissa */
|     3			#define MAX_EXPONENT	0x10000	/* this value causes over/under flow */
|     4			
|     5			typedef struct real {
|     6			    unsigned short  mant[MANT_SIZE];
|     7			    int             exponent;
|     8			    unsigned        sign:1;
|     9			    unsigned        zero:1;
|    10			    unsigned        overflow:1;
|    11			    unsigned        nan:1;
|    12			}               REAL;
|    13			
|    14			REAL           *
|    15			fp_round (fp, bits)
|    16			    struct real    *fp;
00000000' 4e56 0000                     		link a6,#0
00000004' 48e7 3020                     		moveml #0x3020,sp@-
00000008' 246e 0008                     		movel a6@(8),a2
0000000c' 222e 000c                     		movel a6@(12),d1
00000010'                               	LBB2:
|    17			{
|    18			    int             words = bits / 16;
00000010' 2401                          		movel d1,d2
00000012' 6c 04                         		jge L2
00000014' 760f                          		moveq #15,d3
00000016' d283                          		addl d3,d1
00000018'                               	L2:
00000018' e881                          		asrl #4,d1
|    19			
|    20			    int             mask = 1 << (15 - bits % 16);
0000001a' 2002                          		movel d2,d0
0000001c' 6c 04                         		jge L3
0000001e' 760f                          		moveq #15,d3
00000020' d083                          		addl d3,d0
00000022'                               	L3:
00000022' 76f0                          		moveq #-16,d3
00000024' c083                          		andl d3,d0
00000026' 9082                          		subl d2,d0
00000028' 4480                          		negl d0
0000002a' 760f                          		moveq #15,d3
0000002c' 9680                          		subl d0,d3
0000002e' 2003                          		movel d3,d0
00000030' 7401                          		moveq #1,d2
00000032' e1a2                          		asll d0,d2
|    21			
|    22			    if (fp->mant[words] & mask) {
00000034' 4280                          		clrl d0
00000036' 3032 1a 00                    		movew a2@(d1:l:2),d0
0000003a' c082                          		andl d2,d0
0000003c' 67 30                         		jeq L4
|    23				do {
0000003e' 4280                          		clrl d0
00000040'                               	L5:
|    24				    mask += fp->mant[words];
00000040' 3032 1a 00                    		movew a2@(d1:l:2),d0
00000044' d480                          		addl d0,d2
|    25				    fp->mant[words] = mask;
00000046' 3582 1a 00                    		movew d2,a2@(d1:l:2)
|    26				    mask >>= 16;
0000004a' 7610                          		moveq #16,d3
0000004c' e6a2                          		asrl d3,d2
|    27				} while (words--);
0000004e' 51c9 fff0                     		dbra d1,L5
00000052' 4241                          		clrw d1
00000054' 5381                          		subql #1,d1
00000056' 64 e8                         		jcc L5
|    28				if (mask) {	/* Gcc bug: test omitted */
00000058' 67 14                         		jeq L4
|    29				    fp_lshift (fp, 1);
0000005a' 4878 0001                     		pea 1:w
0000005e' 2f0a                          		movel a2,sp@-
00000060' 61ff 00000000*                		jbsr _fp_lshift
|    30				    fp->mant[0] |= 0x8000;
00000066' 0052 8000                     		orw #32768,a2@
|    31				    fp->exponent++;
0000006a' 52aa 0008                     		addql #1,a2@(8)
0000006e'                               	L4:
|    32				}
|    33			    }
|    34			    return fp;
0000006e' 200a                          		movel a2,d0
00000070'                               	LBE2:
|    35			}
00000070' 4cee040c fff4                 		moveml a6@(-12),#0x40c
00000076' 4e5e                          		unlk a6
00000078' 4e75                          		rts
---------------------end test.lst-------------------