[gnu.gcc.bug] bug in -fstrength-reduce optimization

adam@UUNET.UU.NET (Adam de Boor) (06/05/89)

I wish I were better versed in these things (I'll make it there someday),
but... when I turn on -fstrength-reduce for the following loop, gcc produces
code that uses 'i' for 'f', resulting in badness. The code was
compiled on a sun3/50 running SunOS3.5 with gcc version 1.35:

    -g -O -fstrength-reduce -fcombine-regs -W -Wreturn-type -Wunused


======================================================================
q.c:

typedef struct {
    char *name;
    int	offset;
    int length;
    void *type;
} FieldRec, *FieldPtr;

typedef struct {
    short   type;
    union {
	struct {
	    void *fields;
	} StructUnion;
    } data;
} TypeRec, *TypePtr;

main(TypePtr type, int offset)
{
    FieldPtr	f;
    int	    	i;

    f = (FieldPtr)Vector_Data(type->data.StructUnion.fields);

    for (i = Vector_Length(type->data.StructUnion.fields);
	 i > 0;
	 i--)
    {
	if ((f->offset <= offset) && (f->offset + f->length > offset)) {
	    break;
	} else {
	    f++;
	}
    }
}

======================================================================
q.s:
gcc_compiled.:
	.stabs "q.c",100,0,0,Ltext
Ltext:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "void:t15=15",128,0,0,0
.stabs "FieldRec:t16=s16name:17=*2,0,32;offset:1,32,32;\\",128,0,0,0
.stabs "length:1,64,32;type:18=*15,96,32;;",128,0,0,0
.stabs "FieldPtr:t19=*16",128,0,0,0
.stabs "TypeRec:t20=s6type:6,0,16;data:21=u4StructUnion:22=s4fields:18,0,32;;,0,32;;,16,32;;",128,0,0,0
.stabs "TypePtr:t23=*20",128,0,0,0
.text
	.align 1
.globl _main
_main:
	.stabd 68,0,18
	link a6,#0
	moveml #0x2030,sp@-
	movel a6@(8),a2
	movel a6@(12),d2
LBB2:
	.stabd 68,0,22
	movel a2@(2),sp@-
	jbsr _Vector_Data
	movel d0,a3
	.stabd 68,0,24
	movel a2@(2),sp@-
	jbsr _Vector_Length
	movel d0,d1
	jle L3
	movel d0,a0		; << Causes death in cmpl a0@
	addqw #4,a0
L7:
	.stabd 68,0,28
	cmpl a0@,d2		; << choke
	jlt L5
	movel a0@,d0
	addl a3@(8),d0
	cmpl d0,d2
	jlt L3
	.stabd 68,0,29
L5:
	.stabd 68,0,31
	addw #16,a0
	addw #16,a3
	.stabd 68,0,26
	subql #1,d1
	.stabd 68,0,25
	tstl d1
	jgt L7
L3:
LBE2:
	.stabd 68,0,34
	moveml a6@(-12),#0xc04
	unlk a6
	rts
.stabs "main:F1",36,0,0,_main
.stabs "type:p23",160,0,0,8
.stabs "offset:p1",160,0,0,12
.stabs "type:r23",64,0,0,10
.stabs "offset:r1",64,0,0,2
.stabs "f:r19",64,0,0,11
.stabs "i:r1",64,0,0,1
.stabn 192,0,0,LBB2
.stabn 224,0,0,LBE2

======================================================================
q.c.rtl:

;; Function main

(note 1 0 2 ("q.c") 18)

(note 2 1 3 "" -1)

(insn 3 2 4 (set (reg/v:SI 56)
       (mem:SI (plus:SI (reg:SI 14)
               (const_int 8)))) -1 (nil)
   (expr_list:SI (mem:SI (plus:SI (reg:SI 14)
               (const_int 8)))
       (nil)))

(insn 4 3 5 (set (reg/v:SI 57)
       (mem:SI (plus:SI (reg:SI 14)
               (const_int 12)))) -1 (nil)
   (expr_list:SI (mem:SI (plus:SI (reg:SI 14)
               (const_int 12)))
       (nil)))

(note 5 4 6 "" -2)

(note 6 5 7 ("q.c") 22)

(insn 7 6 8 (set (mem:SI (pre_dec:SI (reg:SI 15)))
       (mem/s:SI (plus:SI (reg/v:SI 56)
               (const_int 2)))) -1 (nil)
   (nil))

(insn 8 7 9 (set (reg:SI 60)
       (symbol_ref:SI ("Vector_Data"))) -1 (nil)
   (expr_list:SI (symbol_ref:SI ("Vector_Data"))
       (nil)))

(call_insn 9 8 10 (set (reg:SI 0)
       (call (mem:QI (reg:SI 60))
           (const_int 4))) -1 (nil)
   (nil))

(insn 10 9 11 (set (reg/v:SI 58)
       (reg:SI 0)) -1 (nil)
   (nil))

(note 11 10 12 ("q.c") 24)

(insn 12 11 13 (set (mem:SI (pre_dec:SI (reg:SI 15)))
       (mem/s:SI (plus:SI (reg/v:SI 56)
               (const_int 2)))) -1 (nil)
   (nil))

(insn 13 12 14 (set (reg:SI 61)
       (symbol_ref:SI ("Vector_Length"))) -1 (nil)
   (expr_list:SI (symbol_ref:SI ("Vector_Length"))
       (nil)))

(call_insn 14 13 15 (set (reg:SI 0)
       (call (mem:QI (reg:SI 61))
           (const_int 4))) -1 (nil)
   (nil))

(insn 15 14 16 (set (reg/v:SI 59)
       (reg:SI 0)) -1 (nil)
   (nil))

(insn 16 15 17 (set (reg:SI 15)
       (plus:SI (reg:SI 15)
           (const_int 8))) -1 (nil)
   (nil))

(note 17 16 44 "" -4)

(jump_insn 44 17 45 (set (pc)
       (label_ref 18)) -1 (nil)
   (nil))

(barrier 45 44 43)

(code_label 43 45 22 7)

(note 22 43 23 "" -1)

(note 23 22 24 ("q.c") 28)

(insn 24 23 25 (set (cc0)
       (compare (mem/s:SI (plus:SI (reg/v:SI 58)
                   (const_int 4)))
           (reg/v:SI 57))) -1 (nil)
   (nil))

(jump_insn 25 24 26 (set (pc)
       (if_then_else (le (cc0)
               (const_int 0))
           (pc)
           (label_ref 35))) -1 (nil)
   (nil))

(insn 26 25 27 (set (reg:SI 62)
       (plus:SI (mem/s:SI (plus:SI (reg/v:SI 58)
                   (const_int 4)))
           (mem/s:SI (plus:SI (reg/v:SI 58)
                   (const_int 8))))) -1 (nil)
   (nil))

(insn 27 26 28 (set (cc0)
       (compare (reg:SI 62)
           (reg/v:SI 57))) -1 (nil)
   (nil))

(jump_insn 28 27 29 (set (pc)
       (if_then_else (gt (cc0)
               (const_int 0))
           (pc)
           (label_ref 35))) -1 (nil)
   (nil))

(note 29 28 30 "" -1)

(note 30 29 31 ("q.c") 29)

(jump_insn 31 30 32 (set (pc)
       (label_ref 49)) -1 (nil)
   (nil))

(barrier 32 31 33)

(jump_insn 33 32 34 (set (pc)
       (label_ref 39)) -1 (nil)
   (nil))

(barrier 34 33 35)

(code_label 35 34 36 5)

(note 36 35 37 "" -1)

(note 37 36 38 ("q.c") 31)

(insn 38 37 39 (set (reg/v:SI 58)
       (plus:SI (reg/v:SI 58)
           (const_int 16))) -1 (nil)
   (nil))

(code_label 39 38 40 6)

(note 40 39 41 ("q.c") 26)

(code_label 41 40 42 4)

(insn 42 41 18 (set (reg/v:SI 59)
       (plus:SI (reg/v:SI 59)
           (const_int -1))) -1 (nil)
   (nil))

(code_label 18 42 19 2)

(note 19 18 20 ("q.c") 25)

(insn 20 19 21 (set (cc0)
       (reg/v:SI 59)) -1 (nil)
   (nil))

(jump_insn 21 20 46 (set (pc)
       (if_then_else (gt (cc0)
               (const_int 0))
           (pc)
           (label_ref 49))) -1 (nil)
   (nil))

(jump_insn 46 21 47 (set (pc)
       (label_ref 43)) -1 (nil)
   (nil))

(barrier 47 46 48)

(note 48 47 49 "" -5)

(code_label 49 48 50 3)

(note 50 49 51 "" -3)

(note 51 50 52 "" -6)

(note 52 51 53 ("q.c") 34)

(code_label 53 52 0 1)

======================================================================
q.c.loop:

;; Function main


Loop from 17 to 48: 9 real insns

Insn 38: possible biv, reg 58, const = 16
Insn 42: possible biv, reg 59, const = -1
Reg 59: biv verified
Reg 58: biv verified
Reg 59: initial value reg 0
Reg 58: initial value reg 0
Insn 24: dest address src reg 58 benefit 1 used 1 lifetime 1 replaceable mult 1 add 4
Insn 26: dest address src reg 58 benefit 1 used 1 lifetime 1 replaceable mult 1 add 8
Insn 26: dest address src reg 58 benefit 1 used 1 lifetime 1 replaceable mult 1 add 4
Cannot eliminate biv 59: used outside the loop
Cannot eliminate biv 58: used outside the loop
giv of insn 26 combined with that of 24.
giv of insn 26, no benefit
giv of insn 26 not worth while, 0 vs 9.
giv at 26 reduced to reg 63
giv at 24 reduced to reg 63
giv at 26 not reduced
(note 1 0 2 ("q.c") 18)

(note 2 1 3 "" -1)

(insn 3 2 4 (set (reg/v:SI 56)
       (mem:SI (plus:SI (reg:SI 14)
               (const_int 8)))) -1 (nil)
   (expr_list:SI (mem:SI (plus:SI (reg:SI 14)
               (const_int 8)))
       (nil)))

(insn 4 3 5 (set (reg/v:SI 57)
       (mem:SI (plus:SI (reg:SI 14)
               (const_int 12)))) -1 (nil)
   (expr_list:SI (mem:SI (plus:SI (reg:SI 14)
               (const_int 12)))
       (nil)))

(note 5 4 6 "" -2)

(note 6 5 7 ("q.c") 22)

(insn 7 6 8 (set (mem:SI (pre_dec:SI (reg:SI 15)))
       (mem/s:SI (plus:SI (reg/v:SI 56)
               (const_int 2)))) -1 (nil)
   (nil))

(insn 8 7 9 (set (reg:SI 60)
       (symbol_ref:SI ("Vector_Data"))) -1 (nil)
   (expr_list:SI (symbol_ref:SI ("Vector_Data"))
       (nil)))

(call_insn 9 8 10 (set (reg:SI 0)
       (call (mem:QI (reg:SI 60))
           (const_int 4))) -1 (nil)
   (nil))

(insn 10 9 11 (set (reg/v:SI 58)
       (reg:SI 0)) -1 (nil)
   (nil))

(note 11 10 12 ("q.c") 24)

(insn 12 11 13 (set (mem:SI (pre_dec:SI (reg:SI 15)))
       (mem/s:SI (plus:SI (reg/v:SI 56)
               (const_int 2)))) -1 (nil)
   (nil))

(insn 13 12 14 (set (reg:SI 61)
       (symbol_ref:SI ("Vector_Length"))) -1 (nil)
   (expr_list:SI (symbol_ref:SI ("Vector_Length"))
       (nil)))

(call_insn 14 13 15 (set (reg:SI 0)
       (call (mem:QI (reg:SI 61))
           (const_int 4))) -1 (nil)
   (nil))

(insn 15 14 16 (set (reg/v:SI 59)
       (reg:SI 0)) -1 (nil)
   (nil))

(insn 16 15 54 (set (reg:SI 15)
       (plus:SI (reg:SI 15)
           (const_int 8))) -1 (nil)
   (nil))

(insn 54 16 56 (set (cc0)
       (reg/v:SI 59)) -1 (nil)
   (nil))

(jump_insn 56 54 58 (set (pc)
       (if_then_else (gt (cc0)
               (const_int 0))
           (pc)
           (label_ref 55))) -1 (nil)
   (nil))

(insn 58 56 17 (set (reg:SI 63)
       (plus:SI (reg:SI 0)
           (const_int 4))) -1 (nil)
   (nil))

(note 17 58 43 "" -4)

(code_label 43 17 22 7)

(note 22 43 23 "" -1)

(note 23 22 24 ("q.c") 28)

(insn 24 23 25 (set (cc0)
       (compare (mem/s:SI (reg:SI 63))
           (reg/v:SI 57))) -1 (nil)
   (nil))

(jump_insn 25 24 26 (set (pc)
       (if_then_else (le (cc0)
               (const_int 0))
           (pc)
           (label_ref 35))) -1 (nil)
   (nil))

(insn 26 25 27 (set (reg:SI 62)
       (plus:SI (mem/s:SI (reg:SI 63))
           (mem/s:SI (plus:SI (reg/v:SI 58)
                   (const_int 8))))) -1 (nil)
   (nil))

(insn 27 26 28 (set (cc0)
       (compare (reg:SI 62)
           (reg/v:SI 57))) -1 (nil)
   (nil))

(jump_insn 28 27 29 (set (pc)
       (if_then_else (gt (cc0)
               (const_int 0))
           (label_ref 49)
           (pc))) -1 (nil)
   (nil))

(note 29 28 30 "" -1)

(note 30 29 35 ("q.c") 29)

(code_label 35 30 36 5)

(note 36 35 37 "" -1)

(note 37 36 57 ("q.c") 31)

(insn 57 37 38 (set (reg:SI 63)
       (plus:SI (reg:SI 63)
           (const_int 16))) -1 (nil)
   (nil))

(insn 38 57 40 (set (reg/v:SI 58)
       (plus:SI (reg/v:SI 58)
           (const_int 16))) -1 (nil)
   (nil))

(note 40 38 42 ("q.c") 26)

(insn 42 40 19 (set (reg/v:SI 59)
       (plus:SI (reg/v:SI 59)
           (const_int -1))) -1 (nil)
   (nil))

(note 19 42 20 ("q.c") 25)

(insn 20 19 21 (set (cc0)
       (reg/v:SI 59)) -1 (nil)
   (nil))

(jump_insn 21 20 48 (set (pc)
       (if_then_else (gt (cc0)
               (const_int 0))
           (label_ref 43)
           (pc))) -1 (nil)
   (nil))

(note 48 21 55 "" -5)

(code_label 55 48 49 8)

(code_label 49 55 50 3)

(note 50 49 52 "" -3)

(note 52 50 0 ("q.c") 34)

======================================================================

If you need any of the other rtl dumps, I'll be glad to provide them.


a