On 13/5/15 8:12 PM, Richard Sandiford wrote:
> Chung-Lin Tang <clt...@codesourcery.com> writes:
>> 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 agree this is safer.  However, there used to be some ports that
> use (plus pic_offset_table_rtx (symbol_ref X)) -- i.e. without an unspec --
> to represent a PIC reference to X.  That always seemed semantically wrong,
> since you're not actually adding the address of X and the PIC register,
> but the patch wouldn't handle that case correctly.

Well I can't help those targets then, but at least nothing will be
changed for them by this patch. It will just continue to return 'true'.

> An alternative might be to remove the pic_offset_table_rtx case altogether
> and rely on targetm.delegitimize_address instead.  FWIW, I'd prefer that
> if it works, but it's not me you need to convince. :-)

Like we discussed below, I think the direction should be towards making
things more machine-independent, rather then pushing more into the backend.

>> 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.
> 
> Yeah, maybe we could try to introduce some target-independent knowledge
> of certain reloc types, a bit like the generic BFD_RELOC_*s in bfd.


FWIW, I've ran tests on the newer patch on i686-linux, with no
regressions. Testcase has been moved to gcc.dg/torture by recommendation
of Bernhard. If any of the RTL maintainers can give an eye of merciful
approval, this old PR could be resolved :)

Thanks,
Chung-Lin

Index: rtlanal.c
===================================================================
--- rtlanal.c   (revision 199474)
+++ 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:
Index: testsuite/gcc.dg/torture/pr32219.c
===================================================================
--- testsuite/gcc.dg/torture/pr32219.c  (revision 0)
+++ testsuite/gcc.dg/torture/pr32219.c  (revision 0)
@@ -0,0 +1,12 @@
+/* PR target/32219 */
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-options "-fPIC" { target fpic } } */
+
+extern void f() __attribute__((weak,visibility("hidden")));
+int main()
+{
+  if (f)
+    f();
+  return 0;
+}

Reply via email to