This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: long long move bug?
- To: Becky Gill <bgill at ibmoto dot com>
- Subject: Re: long long move bug?
- From: Dale Johannesen <dalej at apple dot com>
- Date: Tue, 5 Jun 2001 19:06:28 -0700
- Cc: gcc at gcc dot gnu dot org
On Monday, June 4, 2001, at 01:24 PM, Becky Gill wrote:
> All,
>
> I ran into a problem this week when running code with lots of long long
> variables (which eventually start causing spills). Whenever gcc spills
> a long
> long, reloads it, and then copies it to another pair of registers, it
> seems to
> be confused about which registers to use for the copy.
>
> Here's a snippet of asm from objdump:
>
> lwz r10,48(r1) /* reload the long long you spilled
> previously */
> lwz r11,52(r1) /* r10 = upper32 bits, r11 = lower32 bits */
>
> /* do the copy */
> mr r12,r11 /* r12 has copy of lower32_bits */
> mr r11,r10 /* r11 has copy of upper32_bits */
>
> addc r9,r11,r12 /* Do the 64-bit *2 using reg+reg */
> adde r8,r10,r11
I've confirmed that this happens on Darwin (with 2.95.3), but only with
-static. Looks like it's allocating a new register, and doesn't notice
that r11 is in use because it's the upper half of r10:DI. For some
reason using pic makes this go away; the addc/adde pattern is not
generated at all. Instead it uses <<1. I'm not convinced the bug is
actually fixed though; the addc/adde pattern obviously comes from
*adddi3_noppc64, and that pattern is unchanged from 2.95 to 3. (There
is a comment that alludes to this exact problem, too:
;; Define the DImode operations that can be done in a small number
;; of instructions. The & constraints are to prevent the register
;; allocator from allocating registers that overlap with the inputs
;; (for example, having an input in 7,8 and an output in 6,7). We
;; also allow for the output being the same as one of the inputs.
but apparently it doesn't always work that way.)