Created attachment 23527 [details] reduced testcase Compiler output: $ gcc -O testcase.c testcase.c: In function 'foo': testcase.c:7:3: internal compiler error: in gen_lowpart_general, at rtlhooks.c:51 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. (gdb) bt #0 fancy_abort (file=0x115e428 "/mnt/svn/gcc-trunk/gcc/rtlhooks.c", line=51, function=0x115e490 "gen_lowpart_general") at /mnt/svn/gcc-trunk/gcc/diagnostic.c:892 #1 0x0000000000874ccb in gen_lowpart_general (mode=SFmode, x=<value optimized out>) at /mnt/svn/gcc-trunk/gcc/rtlhooks.c:51 #2 0x000000000069bb04 in extract_bit_field (str_rtx=<value optimized out>, bitsize=<value optimized out>, bitnum=<value optimized out>, unsignedp=<value optimized out>, packedp=<value optimized out>, target=<value optimized out>, mode=SFmode, tmode=SFmode) at /mnt/svn/gcc-trunk/gcc/expmed.c:1684 #3 0x00000000006a9562 in expand_expr_real_1 (exp=0x7ffff5ba5280, target=<value optimized out>, tmode=SFmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at /mnt/svn/gcc-trunk/gcc/expr.c:9211 #4 0x00000000006af03d in expand_expr_real (exp=0x7ffff5ba5280, target=<value optimized out>, tmode=<value optimized out>, modifier=<value optimized out>, alt_rtl=<value optimized out>) at /mnt/svn/gcc-trunk/gcc/expr.c:7206 #5 expand_expr_real (exp=0x7ffff5ba5280, target=<value optimized out>, tmode=<value optimized out>, modifier=<value optimized out>, alt_rtl=<value optimized out>) at /mnt/svn/gcc-trunk/gcc/expr.c:7174 #6 0x00000000006ab820 in expand_expr (exp=0x7ffff5ba41b8, target=0x7ffff5b948e0, tmode=SFmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at /mnt/svn/gcc-trunk/gcc/expr.h:422 #7 expand_expr_real_1 (exp=0x7ffff5ba41b8, target=0x7ffff5b948e0, tmode=SFmode, modifier=EXPAND_NORMAL, alt_rtl=0x0) at /mnt/svn/gcc-trunk/gcc/expr.c:8807 #8 0x00000000008d065b in expand_expr (retval=0x7ffff7ff91f8) at /mnt/svn/gcc-trunk/gcc/expr.h:422 #9 expand_return (retval=0x7ffff7ff91f8) at /mnt/svn/gcc-trunk/gcc/stmt.c:1812 #10 0x00000000005e0e8b in expand_gimple_stmt_1 (stmt=0x7ffff5b89510) at /mnt/svn/gcc-trunk/gcc/cfgexpand.c:1951 #11 expand_gimple_stmt (stmt=0x7ffff5b89510) at /mnt/svn/gcc-trunk/gcc/cfgexpand.c:2080 #12 0x00000000005e2f29 in expand_gimple_basic_block (bb=0x7ffff5b851a0) at /mnt/svn/gcc-trunk/gcc/cfgexpand.c:3609 #13 0x00000000005e81d9 in gimple_expand_cfg () at /mnt/svn/gcc-trunk/gcc/cfgexpand.c:4092 #14 0x00000000007f7056 in execute_one_pass (pass=0x1638ac0) at /mnt/svn/gcc-trunk/gcc/passes.c:1556 #15 0x00000000007f7355 in execute_pass_list (pass=0x1638ac0) at /mnt/svn/gcc-trunk/gcc/passes.c:1611 #16 0x000000000093a2b6 in tree_rest_of_compilation (fndecl=0x7ffff5b86f00) at /mnt/svn/gcc-trunk/gcc/tree-optimize.c:422 #17 0x0000000000b02312 in cgraph_expand_function (node=0x7ffff5ba6000) at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1576 #18 0x0000000000b04a5a in cgraph_expand_all_functions () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1635 #19 cgraph_optimize () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1899 #20 0x0000000000b04fda in cgraph_finalize_compilation_unit () at /mnt/svn/gcc-trunk/gcc/cgraphunit.c:1096 #21 0x00000000005097bc in c_write_global_declarations () at /mnt/svn/gcc-trunk/gcc/c-decl.c:9872 #22 0x00000000008e3248 in compile_file (argc=13, argv=0x7fffffffdbd8) at /mnt/svn/gcc-trunk/gcc/toplev.c:591 #23 do_compile (argc=13, argv=0x7fffffffdbd8) at /mnt/svn/gcc-trunk/gcc/toplev.c:1900 #24 toplev_main (argc=13, argv=0x7fffffffdbd8) at /mnt/svn/gcc-trunk/gcc/toplev.c:1963 #25 0x00007ffff6446bbd in __libc_start_main () from /lib/libc.so.6 #26 0x00000000004f036d in _start () Tested revisions: r170622 - crash 4.5 r170013 - crash 4.4 r170013 - crash 4.4.5 (release checking) - crash 4.3.5 (release checking) - OK Maybe it's a regression from 4.3.
Created attachment 23528 [details] reduced testcase http://gcc.gnu.org/bugzilla/attachment.cgi?id=23527&action=edit is for PR47967
Confirmed. #1 0x000000000098a3b8 in gen_lowpart_general (mode=SFmode, x=0x7ffff5b36900) at /space/rguenther/src/svn/trunk/gcc/rtlhooks.c:51 51 gcc_assert (result != 0); (gdb) p x $1 = (rtx) 0x7ffff5b36900 (gdb) call debug_rtx (x) (reg:DF 64) Happens during expanding of BIT_FIELD_REF <f4.0_2, 32, 0> from ;; Function foo (foo) foo (double2 d2) { float D.2687; vector(4) float f4.0; # BLOCK 2 freq:10000 # PRED: ENTRY [100.0%] (fallthru,exec) f4.0_2 = VIEW_CONVERT_EXPR<vector(4) float>(d2_1(D)); D.2687_3 = BIT_FIELD_REF <f4.0_2, 32, 0>; return D.2687_3;
We call extract_bit_field SFmode [0, 32] on (subreg:V4SF (reg/v:V2DF 62 [ d2 ]) 0) which then ends up using the vec_extract optabs, but those are obviously not designed for a mode-changing extraction (and we stripped the subreg before using it - whether that's a good idea is another question). We try to find a "better" vector mode but end up with V2DF again because we want to preserve NUNITS of the inner reg (for whatever reason again). We can obviously guard the vec_extract optab use by GET_MODE_INNER (GET_MODE (op0)) == tmode, but we can as well try to find a "better" mode that also is going to work ... Testing a patch, CCing Andrew who added this code. Patch: Index: gcc/expmed.c =================================================================== --- gcc/expmed.c (revision 170649) +++ gcc/expmed.c (working copy) @@ -1205,7 +1205,6 @@ extract_bit_field_1 (rtx str_rtx, unsign && GET_MODE_INNER (GET_MODE (op0)) != tmode) { enum machine_mode new_mode; - int nunits = GET_MODE_NUNITS (GET_MODE (op0)); if (GET_MODE_CLASS (tmode) == MODE_FLOAT) new_mode = MIN_MODE_VECTOR_FLOAT; @@ -1221,8 +1220,7 @@ extract_bit_field_1 (rtx str_rtx, unsign new_mode = MIN_MODE_VECTOR_INT; for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode)) - if (GET_MODE_NUNITS (new_mode) == nunits - && GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0)) + if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0)) && targetm.vector_mode_supported_p (new_mode)) break; if (new_mode != VOIDmode)
Btw, I wonder since when (and why) we accept float4 f4 = (float4) d2; as valid code.
The testcase is accepted (compiles fine) by 3.3.6, 3.4.6, 4.0.4, 4.1.2, 4.2.4, 4.3.5. The are files in the testsuite that use that style, at least gcc.c-torture/compile/vector-[123].c Changing the code to float4 f4 = *(float4 *) &d2; doesn't prevent the crash
Created attachment 23532 [details] testcase using long instead of double This one fails the same way.
(In reply to comment #3) > Patch: > > Index: gcc/expmed.c IIRC this is the patch which I had applied to the PS3 toolchain while at Sony. I don't have access to the sources any more so I cannot check. But it looks correct. Thanks, Andrew Pinski
(In reply to comment #4) > Btw, I wonder since when (and why) we accept > > float4 f4 = (float4) d2; > > as valid code. Because it is documented as being valid code that is you can cast between the same size of the vectors (not to mention integers that are the same size as the vector also). It acts like a bitwise conversion rather than a promotion. This is needed for compatibility with the Altivec and SPU specs. -- Andrew
Author: rguenth Date: Fri Mar 4 10:31:33 2011 New Revision: 170673 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170673 Log: 2011-03-04 Richard Guenther <rguenther@suse.de> PR middle-end/47968 * expmed.c (extract_bit_field_1): Prefer vector modes that vec_extract patterns can handle. * gcc.dg/torture/pr47968.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr47968.c Modified: trunk/gcc/ChangeLog trunk/gcc/expmed.c trunk/gcc/testsuite/ChangeLog
Fixed.