On 13/5/10 6:37 PM, Richard Sandiford wrote: > Chung-Lin Tang <clt...@codesourcery.com> 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: