Bug 57717

Summary: error: unrecognizable insn compiling ./strtod_l.c from glibc on powerpc-gnuspe
Product: gcc Reporter: Khem Raj <raj.khem>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: amodra, asolokha, bergner, jules, nbkolchin, raj.khem
Priority: P3 Keywords: ice-on-valid-code
Version: 4.9.0   
Target Milestone: ---   
Host: x86_64-linux Target: powerpc-angstrom-linux-gnuspe
Build: x86_64-linux Known to work: 4.7.0, 4.7.1, 4.7.2
Known to fail: 4.8.0, 4.8.1, 4.9.0 Last reconfirmed:
Attachments: testcase
potential fix
testcase

Description Khem Raj 2013-06-25 22:55:52 UTC
Created attachment 30363 [details]
testcase

The attached testcase fails causes a gcc ICE when building for gnuspe targets where -mfloat-gprs=double is used -mfloat-gprs=single works fine

$ ./gcc/cc1 ~/a.c -mfloat-gprs=double

__bswap_32 __bswap_64 atoi atol atoll gnu_dev_major gnu_dev_minor gnu_dev_makedev __libc_use_alloca atof stat lstat fstat fstatat mknod mknodat stat64 lstat64 fstat64 fstatat64 __stat __mknod btowc wctob mbrlen __sigismember __sigaddset __sigdelset pthread_equal __cmsg_nxthdr __ctype_b_loc __ctype_toupper_loc __ctype_tolower_loc tolower toupper __strcspn_c1 __strcspn_c2 __strcspn_c3 __strspn_c1 __strspn_c2 __strspn_c3 __strpbrk_c2 __strpbrk_c3 __strtok_r_1c __strsep_1c __strsep_2c __strsep_3c get_rounding_mode round_away __mpn_add_1 __mpn_add __mpn_sub_1 __mpn_sub overflow_value underflow_value round_and_return str_to_mpn __mpn_lshift_1 ____strtold_l_internal ____new_strtold_l ldbl_extract_mantissa ldbl_insert_mantissa ldbl_pack ldbl_unpack ldbl_canonicalize ldbl_nearbyint __copysign __copysignf __copysignl default_libc_feholdexcept default_libc_fesetround default_libc_feholdexcept_setround default_libc_fesetenv default_libc_feupdateenv default_libc_feupdateenv_test
Analyzing compilation unit
 {GC 5330k -> 3381k}Performing interprocedural optimizations
 <*free_lang_data> <visibility> <early_local_cleanups> <*free_inline_summary> <emutls> <whole-program>Assembling functions:
 get_rounding_mode round_away overflow_value underflow_value round_and_return str_to_mpn {GC 5341k -> 4033k} ____strtold_l_internal
In file included from ../sysdeps/ieee754/ldbl-128ibm/strtold_l.c:54:0:
./strtod_l.c: In function '____strtold_l_internal':
./strtod_l.c:1778:1: error: unrecognizable insn:
(insn 6071 6070 1650 234 (set (reg:TI 4 4)
        (mem/c:TI (plus:SI (reg:SI 5 5)
                (const_int 2032 [0x7f0])) [0 %sfp+2032 S16 A128])) ./strtod_l.c:1002 -1
     (nil))
./strtod_l.c:1778:1: internal compiler error: in extract_insn, at recog.c:2158
0x7ec4c5 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
        ../../gcc/gcc/rtl-error.c:109
0x7ec4f9 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
        ../../gcc/gcc/rtl-error.c:117
0x7bf4c3 extract_insn(rtx_def*)
        ../../gcc/gcc/recog.c:2158
0x7bf534 extract_insn_cached(rtx_def*)
        ../../gcc/gcc/recog.c:2061
0x61f0a6 cleanup_subreg_operands(rtx_def*)
        ../../gcc/gcc/final.c:2998
0x7eb7b6 reload(rtx_def*, int)
        ../../gcc/gcc/reload1.c:1240
0x70637b do_reload
        ../../gcc/gcc/ira.c:4701
0x70637b rest_of_handle_reload
        ../../gcc/gcc/ira.c:4801

This has been seen on trunk and 4.8 branch works ok on 4.7 and below
Comment 1 Khem Raj 2013-06-25 22:58:52 UTC
I have tracked it down to this commit

Author: amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Jul 24 05:55:50 2012 +0000
  
        PR target/53914
        PR target/54009
        * config/rs6000/constraints.md (Y): Use mem_operand_gpr.
        * config/rs6000/predicates.md (word_offset_memref_operand): Delete.
        Adjust all rs6000_legitimate_offset_address_p calls.
        * config/rs6000/rs6000-protos.h (mem_operand_gpr): Declare.
        (rs6000_secondary_reload_gpr): Declare.
        (rs6000_legitimate_offset_address_p): Update prototype.
        (rs6000_offsettable_memref_p): Delete.
        (rs6000_secondary_reload_ppc64): Delete.
        * config/rs6000/rs6000.c (address_offset): New function.
        (mem_operand_gpr): Likewise.
        (rs6000_legitimate_offset_address_p): Add worst_case param.  When
        not worst_case assume class of regs with least restrictive offsets.
        Adjust all calls.
        (legitimate_lo_sum_address_p): Simplify register mode tests.
        (rs6000_legitimize_address): Likewise.  Assume best case offset
        addressing.  Combine ELF and MACHO lo_sum code.
        (rs6000_mode_dependent_address): Correct offset addressing limits.
        (rs6000_offsettable_memref_p): Make static, add reg_mode param.
        Use reg_mode to help rs6000_legitimate_offset_address_p.
        (rs6000_secondary_reload): Use address_offset.  Handle 32-bit multi
        gpr load/store when offset too large.
        (rs6000_secondary_reload_gpr): Renamed rs6000_secondary_reload_ppc64.
        (rs6000_split_multireg_move): Adjust rs6000_offsettable_memref_p calls.
        * config/rs6000/rs6000.md (movdf_hardfloat32): Use 'Y' constraint
        for gpr load/store.  Order alternatives as r->Y,Y->r,r->r and
        d->m,m->d,d->d.  Correct size of gpr load/store.
        (movdf_softfloat32): Use 'Y' constraint for gpr load/store.  Order
        alternatives.
        (movti_ppc64): Likewise.
        (movdi_internal32): Likewise.  Also disparage fprs.
        (movdi_mfpgpr, movdi_internal64): Likewise.
        (movtf_internal): Use 'm' for fpr load/store.  Order alternatives.
        (movtf_softfloat): Order alternatives.
        (extenddftf2_internal): Use 'm' and 'Y' for store.
        (movti_power, movti_string): Use 'Y' for gpr load/store.  Order.
        (stack_protect_setdi, stack_protect_testdi): Likewise.
        (movdf_hardfloat64_mfpgpr, movdf_hardfloat64): Order alternatives.
        (movdf_softfloat64): Likewise.
        (reload_<mode>_store): Adjust reload_di_store to provide
        reload_si_store as well.
        (reload_<mode>_load): Likewise.
Comment 2 Khem Raj 2013-06-25 23:00:56 UTC
This is how gcc is configured

Target: powerpc-angstrom-linux-gnuspe
Configured with: ../gcc/configure --build=x86_64-linux --host=x86_64-linux --target=powerpc-angstrom-linux-gnuspe --prefix=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr --exec_prefix=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr --bindir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/bin/ppce500v2-angstrom-linux-gnuspe.gcc-cross-initial --sbindir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/bin/ppce500v2-angstrom-linux-gnuspe.gcc-cross-initial --libexecdir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/libexec/ppce500v2-angstrom-linux-gnuspe.gcc-cross-initial --datadir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/share --sysconfdir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/etc --sharedstatedir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/com --localstatedir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/var --libdir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/lib/ppce500v2-angstrom-linux-gnuspe.gcc-cross-initial --includedir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/include --oldincludedir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/include --infodir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/share/info --mandir=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux/usr/share/man --disable-silent-rules --disable-dependency-tracking --with-libtool-sysroot=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/x86_64-linux --with-newlib --without-headers --disable-shared --disable-threads --disable-multilib --disable-__cxa_atexit --enable-languages=c --program-prefix=powerpc-angstrom-linux-gnuspe- --with-sysroot=/builds1/angstrom/build/tmp-angstrom_next-eglibc/sysroots/p2020ds --with-build-sysroot=/builds1/angstrom/build/tmp-angstrom_next-eglibc/work/ppce500v2-angstrom-linux-gnuspe/gcc-cross-initial/4.8.1-r0/gcc-4.8.1/build.x86_64-linux.powerpc-angstrom-linux-gnuspe/tmpsysroot --disable-libmudflap --disable-libgomp --disable-libssp --disable-libquadmath --with-system-zlib --disable-lto --disable-plugin --enable-decimal-float=no --enable-e500_double --disable-nls --with-long-double-128


Thread model: single
gcc version 4.9.0 20130625 (experimental) (GCC)
Comment 3 Alan Modra 2013-06-27 09:05:54 UTC
Created attachment 30383 [details]
potential fix

This reverts part of the patch identified in comment #1, and cures the testcase failure.
Comment 4 Khem Raj 2013-06-28 02:25:54 UTC
I have backported this fix to 4.8 branch and tested it and it fixed the issue. Below is the patch for 4.8


Index: gcc-4.8.1/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc-4.8.1.orig/gcc/config/rs6000/rs6000.c   2013-05-09 18:54:06.000000000 -0700
+++ gcc-4.8.1/gcc/config/rs6000/rs6000.c        2013-06-27 08:22:40.459021366 -0700
@@ -5431,11 +5431,12 @@

     case TFmode:
     case TDmode:
-    case TImode:
       if (TARGET_E500_DOUBLE)
        return (SPE_CONST_OFFSET_OK (offset)
                && SPE_CONST_OFFSET_OK (offset + 8));
+        /* Fall through.  */

+    case TImode:
       extra = 8;
       if (!worst_case)
        break;
Comment 5 Alexandru-Cezar Sărdan 2013-07-12 14:10:11 UTC
Created attachment 30500 [details]
testcase

The attached test case causes another ICE if gcc is compiled for gnuspe targets after the patch proposed in comment #4 is applied and -mfloat-gprs=double is used.
Also -mfloat-gprs=single works fine.

$ ./gcc/cc1 -m32 -mcpu=8548 -mabi=spe -mspe -mfloat-gprs=double ~/test.c 
 __bswap_32 __bswap_64 create_Result_file main
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <early_local_cleanups> <*free_inline_summary> <whole-program>Assembling functions:
 create_Result_file
/home/alex/test.c: In function 'create_Result_file':
/home/alex/test.c:43:1: internal compiler error: in change_address_1, at emit-rtl.c:2019
 }
 ^
Comment 6 Khem Raj 2013-07-16 01:57:17 UTC
here is another case which fails before suggested patch and also after the patch

void foo()
{

 double a[20000];
 double b = 3.1L / 20000;
}

Here is result below after applying the patch in comment #3

$ ./gcc/cc1 ~/a.c
 foo
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <early_local_cleanups> <*free_inline_summary> <emutls> <whole-program>Assembling functions:
 foo
/homes/kraj/a.c: In function 'foo':
/homes/kraj/a.c:6:1: internal compiler error: in change_address_1, at emit-rtl.c:1955
 }
 ^
0x5d7dd0 change_address_1
        ../../gcc/gcc/emit-rtl.c:1955
0x5dad82 adjust_address_1(rtx_def*, machine_mode, long, int, int, int, long)
        ../../gcc/gcc/emit-rtl.c:2087
0x61ac98 alter_subreg(rtx_def**, bool)
        ../../gcc/gcc/final.c:3062
0x61aed9 cleanup_subreg_operands(rtx_def*)
        ../../gcc/gcc/final.c:3008
0x7e80b6 reload(rtx_def*, int)
        ../../gcc/gcc/reload1.c:1240
0x70227b do_reload
        ../../gcc/gcc/ira.c:4701
0x70227b rest_of_handle_reload
        ../../gcc/gcc/ira.c:4801
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.
Comment 7 jules 2013-08-12 14:06:03 UTC
Here's another candidate patch:

http://gcc.gnu.org/ml/gcc-patches/2013-08/msg00668.html
Comment 8 Alan Modra 2017-12-28 00:04:25 UTC
Seems to be fixed on all active branches, so closing.