This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/58067] ICE in GFortran recog.c:2158
- From: "aoliva at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 06 Aug 2013 22:03:40 +0000
- Subject: [Bug target/58067] ICE in GFortran recog.c:2158
- Auto-submitted: auto-generated
- References: <bug-58067-4 at http dot gcc dot gnu dot org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58067
--- Comment #5 from Alexandre Oliva <aoliva at gcc dot gnu.org> ---
As Andrew says, the problem with -mtls-dialect=gnu (the default) is lack of TLS
support. The tls_get_addr calls expanded by tls_global_dynamic_64_<mode> are
not recognized by the corresponding insns because the call address operand (the
__tls_get_addr symbol_ref) doesn't pass the constant_call_address_operand
predicate, configured to always fail in the LARGE code models. I suppose it's
not appropriate to make an exception for __tls_get_addr, and we'd instead have
to make it an indirect call after loading the address from the GOT. We'd need
new relocations and relaxation smarts in binutils for this to work. I guess it
makes more sense to force the GNU2 tls-dialect for LARGE code models, since
that one works, and maybe switch to it by default in other models; we've had it
for long enough already.
As for the non-delegitimized notes we get in both modes, that's fixed with
something along the lines of the following patch:
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13827,6 +13827,21 @@ ix86_delegitimize_address (rtx x)
x = replace_equiv_address_nv (orig_x, x);
return x;
}
+ if (GET_CODE (x) == PLUS
+ && ix86_pic_register_p (XEXP (x, 0))
+ && GET_CODE (XEXP (x, 1)) == CONST
+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
+ /* These are used in 64-bit CM_LARGE mode. */
+ && (XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_PLTOFF
+ || XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_GOTOFF))
+ {
+ x = simplify_gen_subreg (GET_MODE (orig_x),
+ XVECEXP (XEXP (XEXP (x, 1), 0), 0, 0),
+ GET_MODE (x), 0);
+ if (x == NULL_RTX)
+ return orig_x;
+ return x;
+ }
if (GET_CODE (x) != CONST
|| GET_CODE (XEXP (x, 0)) != UNSPEC
|| (XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL
Uros (or anyone), please take this as a starting point; it might require
support for addends, even though I haven't needed them for this one testcase.
Or maybe we don't need them, after all. I'm not sure, so I'll leave it for
someone else who knows better.