On 2011/4/20 09:24 PM, Richard Sandiford wrote:
> Hi Chung-Lin,
> 
> I'm seeing an ICE with this patch, specifically;
> 
> Chung-Lin Tang <clt...@codesourcery.com> writes:
>> +      if (coproc_p)
>> +    low = SIGN_MAG_LOW_ADDR_BITS (val, 10);
> 
> We generate:
> 
> Reload 1: reload_out (V4SI) = (mem/c:V4SI (plus:SI (plus:SI (reg/f:SI 11 fp)
>                                                             (const_int -6144 
> [0xffffffffffffe800]))
>                                                         (const_int 1020 
> [0x3fc])) [43 %sfp+-5024 S16 A64])
> 
> but 1020 isn't a legitimate offset for V4SI:
> 
>   /* For quad modes, we restrict the constant offset to be slightly less
>      than what the instruction format permits.  We do this because for
>      quad mode moves, we will actually decompose them into two separate
>      double-mode reads or writes.  INDEX must therefore be a valid
>      (double-mode) offset and so should INDEX+8.  */
>   if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
>     return (code == CONST_INT
>           && INTVAL (index) < 1016
>           && INTVAL (index) > -1024
>           && (INTVAL (index) & 3) == 0);
> 
> A simple "fix" would be to use 9 instead of 10, but something a little
> more subtle might be preferred :-)
> 
> Richard

Oh dear, for some reason I mistakenly thought that NEON had a quad-word
load/store, sorry :P

Reducing from 10 to 9 may be a possible solution, if restricted to the
necessary cases. For example:

-low = SIGN_MAG_LOW_ADDR_BITS (val, 10);
+{
+  low = SIGN_MAG_LOW_ADDR_BITS (val, 10);
+
+  /* NEON quad-word load/stores are made of two double-word accesses,
+     so the valid index range is reduced by 8. Treat as 9-bit range if
+     we go over it.  */
+  if (TARGET_NEON && VALID_NEON_QREG_MODE (mode) && low >= 1016)
+    low = SIGN_MAG_LOW_ADDR_BITS (val, 9);
+}

To Richard Earnshaw, how do you think of a fix like this? Or should we
just simply return false under this out-of-range case (it should be rare
I hope).

Thanks,
Chung-Lin

Reply via email to