This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

incorrect code generated by reload


Hello,

this is a call for advise where to focus my attention in order to solve
a problem I'm having with gcc.  First of all the problem appears in a
very old version of gcc, but I need to fix it there anyway for a number
of reasons.  In addition the newest gcc-2.96 simply breaks, compiling
the C source in question, generating unrecognizable insn during reload
pass.  Later on to the last problem, but first thing first.

The following is a fragment of assembler code generated by gcc with
list of flags used, compiler version and target architecture.  The
host side is sun4-solaris (but it seems to be irrelevant)

@ Generated by gcc 2.7.9-970819 for ARM/coff
@ GNU C version 2.7.9-970819 (arm-coff) compiled by GNU C version cygnus-2.7-96q4.
@ options passed:  -mcpu=strongarm110 -mapcs-32 -mno-sched-prolog
@ -mlongcall -ansi -O2 -Wall -ansi -fno-builtin -fvolatile
@ -fno-schedule-insns2
@ options enabled:  -fvolatile -fdefer-pop -fcse-follow-jumps
@ -fcse-skip-blocks -fexpensive-optimizations -fthread-jumps
@ -fstrength-reduce -fpeephole -fforce-mem -ffunction-cse -finline
@ -fkeep-static-consts -fcaller-saves -freg-struct-return
@ -frerun-cse-after-loop -fschedule-insns -fcommon -fverbose-asm
@ -fgnu-linker -mapcs-32 -msoft-float -mno-sched-prolog -mno-sched-prologue
@ -mlongcall -mcpu=strongarm110

 
 1 mvn r9, #5888 @ 1706 *movsi_insn/2
 2 sub r6, fp, #5952 @ 2169 *addsi3_insn/2
 3 sub r6, r6, #20 @ 2170 *addsi3_insn/2
 4 str r9, [r6, #0] @ 1866 *movsi_insn/4
 5 sub r6, fp, #5952 @ 2171 *addsi3_insn/2
 6 sub r6, r6, #20 @ 2172 *addsi3_insn/2
 7 ldr r9, [r6, #0] @ 1872 *movsi_insn/3
 8 sub r9, r9, #5 @ 1707 *addsi3_insn/2
 9 sub r6, fp, #5952 @ 2173 *addsi3_insn/2
10 sub r6, r6, #20 @ 2174 *addsi3_insn/2
11 str r9, [r6, #0] @ 1875 *movsi_insn/4
12 sub r6, fp, #5952 @ 2175 *addsi3_insn/2
13 sub r6, r6, #20 @ 2176 *addsi3_insn/2
14 sub r6, fp, #36 @ 1876 *addsi3_insn/2
15 ldr r9, [r6, #0] @ 1880 *movsi_insn/3
16 ldrh r3, [r6, r9] @ movhi @ 1546 *movhi_insn_arch4/3
17 strh r3, [r7, #138] @ movhi @ 1175 *movhi_insn_arch4/4

Not even mentioning outrageous inefficiency of the code, it
is plain incorrect.  The insns 14 and 15 must be swapped
in order to get correct offset value in r9.  In insn 14
r6 is set before r9 is restored from the address being held
in r6 before insn 14.  All insns except 1, 8, 16 and 17
are generated during reload pass.  Ideally the whole bunch
of insns should be substituted by the following two, giving
the same effect:

 ldrh    r3, [fp, #5847] ; 5888 - 5 -36 = 5847
 strh    r3, [r7, #138]
 

These are fragments of RTL dumps

before reload (from mysource.c.lreg file)

(insn 1706 1171 1707 (set (reg:SI 423)
        (const_int -5889)) 193 {*movsi_insn} (nil)
    (nil))

(insn 1707 1706 1546 (set (reg:SI 423)
        (plus:SI (reg:SI 423)
            (const_int -5))) 6 {*addsi3_insn} (insn_list 1706 (nil))
    (expr_list:REG_EQUAL (const_int -5894)
        (nil)))

(insn 1546 1707 1175 (set (reg:HI 425)
        (mem:HI (plus:SI (reg:SI 25 fp)
                (reg:SI 423)))) 212 {*movhi_insn_arch4} (insn_list 1707 (nil))
    (expr_list:REG_EQUIV (mem:HI (plus:SI (reg:SI 25 fp)
                (reg:SI 423)))
        (nil)))

 
After reload (from mysource.c.greg file)
 
(insn 1867 1875 1877 (clobber (mem:SI (plus:SI (reg:SI 11 fp)
                (const_int -5972)))) -1 (nil)
    (nil))

(insn 1877 1867 1876 (set (reg:SI 6 r6)
        (plus:SI (reg:SI 11 fp)
            (const_int -5972))) 6 {*addsi3_insn} (nil)
    (nil))

(insn 1876 1877 1880 (set (reg:SI 6 r6)
        (plus:SI (reg:SI 11 fp)
            (const_int -36))) 6 {*addsi3_insn} (nil)
    (nil))

(insn 1880 1876 1546 (set (reg:SI 9 r9)
        (mem:SI (reg:SI 6 r6))) -1 (nil)
    (nil))

(insn:QI 1546 1880 1175 (set (reg:HI 3 r3)
        (mem:HI (plus:SI (reg:SI 6 r6)
                (reg:SI 9 r9)))) 212 {*movhi_insn_arch4} (insn_list 1707 (nil))
    (expr_list:REG_EQUIV (mem:HI (plus:SI (plus:SI (reg:SI 11 fp)
                    (mem:SI (plus:SI (reg:SI 11 fp)
                            (const_int -5972))))
                (const_int -36)))
        (nil)))


These are debug_rtx prints of reloads for insn 1546 before and after
subst_reloads () called:

reload_as_needed: before subst_reloads

(insn 1880 1876 1546 (set (reg:SI 9 r9)
        (mem:SI (plus:SI (reg:SI 11 fp)
                (const_int -5972)))) -1 (nil)
    (nil))

(insn:QI 1546 1880 1175 (set (reg:HI 3 r3)
        (mem:HI (plus:SI (plus:SI (reg:SI 11 fp)
                    (const_int -36))
                (mem:SI (plus:SI (reg:SI 11 fp)
                        (const_int -5972)))))) 212 {*movhi_insn_arch4} (insn_list 1707 (nil))
    (expr_list:REG_EQUIV (mem:HI (plus:SI (plus:SI (reg:SI 11 fp)
                    (mem:SI (plus:SI (reg:SI 11 fp)
                            (const_int -5972))))
                (const_int -36)))
        (nil)))

reload_as_needed: after subst_reloads

(insn 1880 1876 1546 (set (reg:SI 9 r9)
        (mem:SI (reg:SI 6 r6))) -1 (nil)
    (nil))

(insn:QI 1546 1880 1175 (set (reg:HI 3 r3)
        (mem:HI (plus:SI (reg:SI 6 r6)
                (reg:SI 9 r9)))) 212 {*movhi_insn_arch4} (insn_list 1707 (nil))
    (expr_list:REG_EQUIV (mem:HI (plus:SI (plus:SI (reg:SI 11 fp)
                    (mem:SI (plus:SI (reg:SI 11 fp)
                            (const_int -5972))))
                (const_int -36)))
        (nil)))


Register 423 was allocated to r6 during local register allocation pass.
Then during reload pass r6 had to be spilled and all subsequent uses
of r6 put on stack if global_alloc () could not allocate another hard
register for the pseudo-registers being allocated to r6, including r423.
Although it is inefficient and ugly, there's nothing wrong with that
in terms of code correctness. But when insn 1546 operands are being
reloaded their order is being switched, which results in incorrect
ordering of reload insns for the insn 1546, generated by emit_reload_insns.
Can anybody help me fix this or at least help me narrow the scope of
the problem?  The same problem may still exist in gcc-2.96 -- I can't
check, because it simply aborts with an unrecognizable insn as I mentioned.

Regards,
Dmitri.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]