This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: problem with subregs.
- From: "Tal Agmon" <Tal dot Agmon at nsc dot com>
- To: "Jim Wilson" <wilson at specifixinc dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 5 Nov 2003 16:33:52 +0200
- Subject: Re: problem with subregs.
Tal Agmon wrote:
>> The compiler can use a pair of HI regs to get a long one but if it uses
a
>> long reg then it cannot refer to it's
>> upper word.
Jim Wilson wrote:
>Try CANNOT_CHANGE_MODE_CLASS. This has various names depending on what
>gcc version you are looking at.
Thank you, I used the macro CANNOT_CHANGE_MODE_CLASS and it worked on most
cases
(I'm using gcc-3.4-20031029). Here is an example where it fails:
In our architecture pointer size is 32 bits and int size is 16 bits. I
tried to compile a program that
contains the line a = &b - &c; (a is int) and the compiler issued the
error:
internal compiler error: in ?, at gcc-3.3.2\gcc\function.c:3776
The insn that cause this is:
(insn 350 1020 351 61 007A63F0 (set (reg:HI 79)
(minus:HI (subreg:HI (reg/v/f:SI 24) 0)
(subreg:HI (reg/f:SI 17 virtual-stack-vars) 0))) -1 (nil)
(nil))
The problem here is in the rtl (subreg:HI (reg/f:SI 17 virtual-stack-vars)
0).
The frame pointer in our architecture is a 32 bits reg and changing the
mode here is not allowed
according to the macro.
This bug can be solved by solving 1 or 2:
1. Actually, what I wish to prevent is subregs like (subreg:HI (reg:SI long
register) 2)
and not subregs like
(subreg:HI (reg:SI long register) 0).
And by using the macro I prevent both and it cause this bug (and also
some decrease in optimizations).
2. Allowing changing SImode to HImode but with some additional move and
scratch regs.
(reload_in and reload_out did not helped in that because they effects only
moves so they will
not work in the case described here).
Regards,
Tal.