Created attachment 30602 [details] a flattened self contained version of the NAS benchmark. When I try to compile one of the NAS benchmark's with -fpic and -mcmodel=large with GCC 4.8.0 up through the current trunk (20130802) I get an internal compiler error. This looks rather similar to PR56797 but that particular bug seems to have been only on ARM and this occurs on x86_64. So it may be that PR56797 is more expansive than initially thought or this might be a different bug. I can't tell. [ben@snog BT-MZ]$ PATH=/home/ben/Work/gcc-test/bin/:$PATH gfortran -c -save-temps -O2 -g -fopenmp -fpic -mcmodel=large bt-all.f bt-all.f: In function ‘MAIN__._omp_fn.1’: bt-all.f:305:0: note: non-delegitimized UNSPEC UNSPEC_PLTOFF (9) found in variable location do iz = 1, proc_num_zones ^ bt-all.f:305:0: note: non-delegitimized UNSPEC UNSPEC_PLTOFF (9) found in variable location bt-all.f: In function ‘MAIN__._omp_fn.0’: bt-all.f:449:0: error: unrecognizable insn: 999 continue ^ (call_insn/u 52 51 53 2 (parallel [ (set (reg:DI 0 ax) (call:DI (mem:QI (symbol_ref:DI ("__tls_get_addr")) [0 S1 A8]) (const_int 0 [0]))) (unspec:DI [ (symbol_ref:DI ("omp_cmn2a_") [flags 0x10] <var_decl 0x7f57f37f9390 omp_cmn2a>) ] UNSPEC_TLS_GD) ]) bt-all.f:48 -1 (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000]) (nil)) (nil)) bt-all.f:449:0: internal compiler error: in extract_insn, at recog.c:2158 0x922c1a _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) ../.././gcc/rtl-error.c:109 0x922c49 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*) ../.././gcc/rtl-error.c:117 0x8f966a extract_insn(rtx_def*) ../.././gcc/recog.c:2158 0x7bdbee instantiate_virtual_regs_in_insn ../.././gcc/function.c:1609 0x7bdbee instantiate_virtual_regs ../.././gcc/function.c:1926 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. This problem doesn't seem to occur except when you have -fpic and -mcmodel=large. Changing the memory model to medium or small or removing the -fpic allows the code to compile. Attached is a flattened self contained version of the NAS benchmark my fortran is not good enough to boil it down into a more parsimonious reproducer.
I don't think -mcmodel=large support has been added for TLS yet.
You can add -mtls-dialect=gnu2 to -fpic and -mcmodel=large.
(In reply to Uroš Bizjak from comment #2) > You can add -mtls-dialect=gnu2 to -fpic and -mcmodel=large. Though doing that prevents the ICE, the compilation spits out about 78 lines like: bt-all.f:453:0: note: non-delegitimized UNSPEC UNSPEC_GOTOFF (1) found in variable location Google doesn't seem to give me any idea as to if I need be concerned about that note.
The note just means the debug info location expression containing this unexpected piece of RTL can't be expressed in dwarf and will thus be dropped on the floor, so you lose a bit of debug info, but that's all.
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.
I just rebuilt the trunk with the patch that Alexandre Oliva provided and I can confirm that it solves the problem with notes about non-delegitimized addresses. However, I haven't yet tested the DWARF to make sure that it works as expected. If we do make -mtls-dialect=gnu2 the default or even implied when you specify -mcmodel=large, won't you still need to fix the problem with the unknown instruction just in case someone does -mtls-dialect=gnu or will you just error out saying: "-mcmodel=large is not supported within -mtls-dialect=gnu". Personally, I believe that erroring out that way is perfectly acceptable.
Created attachment 30622 [details] Alexandre's patch as a file rather than as text.
Created attachment 30646 [details] gnu largepic TLS An attempt to handle -mcmodel=large -fpic TLS GD/LD in the compiler. Seems to work for me on testcase like: __thread int a; static __thread int b; int foo () { return a++ + b++; } int main () { return foo () + foo () - 2; } but unfortunately ld will fail if this code is being attempted to link into an executable or PIE: /usr/bin/ld: /tmp/ccWao1Is.o: TLS transition from R_X86_64_TLSGD to R_X86_64_GOTTPOFF against `a' at 0x26 in section `.text' failed /tmp/ccWao1Is.o: could not read symbols: Bad value collect2: error: ld returned 1 exit status
Author: jakub Date: Wed Aug 14 09:09:58 2013 New Revision: 201720 URL: http://gcc.gnu.org/viewcvs?rev=201720&root=gcc&view=rev Log: PR target/58067 * config/i386/i386.c (ix86_delegitimize_address): For CM_MEDIUM_PIC and CM_LARGE_PIC ix86_cmodel fall thru into the -m32 code, handle there also UNSPEC_PLTOFF. Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.c Author: jakub Date: Wed Aug 14 09:29:22 2013 New Revision: 201721 URL: http://gcc.gnu.org/viewcvs?rev=201721&root=gcc&view=rev Log: PR target/58067 * config/i386/i386.c (ix86_delegitimize_address): For CM_MEDIUM_PIC and CM_LARGE_PIC ix86_cmodel fall thru into the -m32 code, handle there also UNSPEC_PLTOFF. Modified: branches/gcc-4_8-branch/gcc/ChangeLog branches/gcc-4_8-branch/gcc/config/i386/i386.c
Author: jakub Date: Wed Aug 28 16:31:41 2013 New Revision: 202055 URL: http://gcc.gnu.org/viewcvs?rev=202055&root=gcc&view=rev Log: PR target/58067 * config/i386/i386.md (*tls_global_dynamic_64_largepic): New insn. (*tls_local_dynamic_base_64_largepic): Likewise. (tls_global_dynamic_64_<mode>, tls_local_dynamic_base_64_<mode>): Remove predicate from call operand. * config/i386/i386.c (ix86_tls_get_addr): For -mcmodel=large -fpic return sum of pic_offset_table_rtx and UNSPEC_PLTOFF of the symbol. Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.c trunk/gcc/config/i386/i386.md
Is this issue fixed on trunk? The bug is still in state UNCONFIRMED. Just hit this on the google/4_8 branch, since the last fix (r202055) wasn't backported to gcc-4_8. I am going to backport r202055 to google/4_8 as that seems to fix the problem. Google ref b/15576865. Thanks, Teresa
At least the C testcase in comment 8 was fixed for 4.9 and subsequent releases.
Even the original fortran testcase does not fail in 8.3.1, 9.3.0, 10.3.0, 11.1.0 for me.
*** Bug 46250 has been marked as a duplicate of this bug. ***
Fixed. There is PR 79497 for the non PIC case with global-dynamic TLS.