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]
Other format: [Raw text]

Illegal code generation: gcc-3.2 --target=m68k-elf


I'm having trouble using gcc-3.2 to build a linux kernel.  I've found
a case of illegal code geneation for gcc-3.2 with -m5200.

I'm in the midst of cutting the testcase down to a few lines, but the
crux of the problem is that I have a local variable that is a short
that is being incremented  The variable itself has been pushed into
the stack, and since the ColdFire can't add shorts, the initial
RTL(from yy.c.00.rtl) looks like:

(note 688 687 689 ("yy.c") 3539)

(insn 689 688 690 (set (reg:SI 187)
        (plus:SI (subreg:SI (reg/v:HI 40) 0)
            (const_int 1 [0x1]))) -1 (nil)
    (nil))

(insn 690 689 691 (set (reg/v:HI 40)
        (subreg:HI (reg:SI 187) 2)) -1 (nil)
    (nil))

Which is fine.

>From yy.c.15.life:

(note 688 687 689 ("yy.c") 3539)

(insn 689 688 690 (set (reg:SI 187)
        (plus:SI (subreg:SI (reg/v:HI 40) 0)
            (const_int 1 [0x1]))) 99 {*addsi3_5200} (nil)
    (expr_list:REG_DEAD (reg/v:HI 40)
        (nil)))

(insn 690 689 691 (set (reg/v:HI 40)
        (subreg:HI (reg:SI 187) 2)) 33 {*m68k.md:1024} (insn_list 689 (nil))
    (expr_list:REG_DEAD (reg:SI 187)
        (nil)))

So far the register death information looks correct.  From yy.c.16.combine:

(note 688 687 689 ("yy.c") 3539)

(note 689 688 690 NOTE_INSN_DELETED)

(insn 690 689 691 (set (subreg:SI (reg/v:HI 40) 0)
        (plus:SI (subreg:SI (reg/v:HI 40) 0)
            (const_int 1 [0x1]))) 99 {*addsi3_5200} (nil)
    (nil))


Looks like combine put the two instructions together, but there is no
instruction in the ColdFire that can allow for this to happen (I guess
it found the pattern for addhi3 and assumed that it is valid for
ColdFire?).  Somewhere its decided that (reg HI:40) won't live in a
register, so its put on the stack in slot -430, and the RTL is fixed
up to refer to it that way. the RTL stays the same until yy.c.21.greg:

(note 688 687 689 ("yy.c") 3539)

(note 689 688 1150 NOTE_INSN_DELETED)

(insn 1150 689 690 (set (reg:SI 0 %d0)
        (const_int 1 [0x1])) 30 {*m68k.md:993} (nil)
    (nil))

(insn 690 1150 691 (set (mem:SI (plus:SI (reg/f:SI 14 %a6)
                (const_int -428 [0xfffffe54])) [0 rotate S4 A16])
        (plus:SI (mem:SI (plus:SI (reg/f:SI 14 %a6)
                    (const_int -428 [0xfffffe54])) [0 rotate S4 A16])
            (reg:SI 0 %d0))) 99 {*addsi3_5200} (nil)
    (nil))

Now the RTL is bogus since the store to memory is *SImode* wide
whereas the original variable is HImode.  From further inspection of
the assembler output of this function, I find the same results of
operations invoving AND and OR with this same variable.

As a test, I removed the addhi3 pattern, and the problem still persists.

Does anyone have any ideas why this is happening, and how I can
prevent it from happening?  

As soon as I can cut the testcase down from a few thousand lines, I'll
submit it as a bug.

All ideas are appreciated.

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)


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