On 13/5/10 6:37 PM, Richard Sandiford wrote:
> Chung-Lin Tang <[email protected]> writes:
>> + case UNSPEC:
>> + /* Reach for a contained symbol. */
>> + return nonzero_address_p (XVECEXP (x, 0, 0));
>
> I don't think this is safe. UNSPECs really are unspecified :-),
> so we can't assume that (unspec X) is nonzero simply because X is.
Attached is a modified patch (not yet tested but just for demonstration)
with a more specific test, hopefully regarded as more safe.
The point is in recognizing (const (unspec [symbol] XYZ)) offsets in PIC
references, which seems quite idiomatic across all targets by now.
I would suggest that this probably means there should be a new, more
specific construct in RTL to represent relocation values of this kind,
instead of (const (unspec)) serving an unofficial role; possibly some
real support for reasoning about PIC references could also be considered.
Chung-Lin
Index: rtlanal.c
===================================================================
--- rtlanal.c (revision 198923)
+++ rtlanal.c (working copy)
@@ -393,7 +393,15 @@ nonzero_address_p (const_rtx x)
/* Handle PIC references. */
if (XEXP (x, 0) == pic_offset_table_rtx
&& CONSTANT_P (XEXP (x, 1)))
- return true;
+ {
+ rtx offset = XEXP (x, 1);
+ if (GET_CODE (offset) == CONST
+ && GET_CODE (XEXP (offset, 0)) == UNSPEC
+ && GET_CODE (XVECEXP (XEXP (offset, 0), 0, 0)) == SYMBOL_REF)
+ return nonzero_address_p (XVECEXP (XEXP (offset, 0), 0, 0));
+
+ return true;
+ }
return false;
case PRE_MODIFY: