Created attachment 26910 [details] ffi.i from src/ia64/ffi.c This isn't my code, but from the libffi package. Attached is the preprocessor output, and the complete error output looks like depbase=`echo src/ia64/ffi.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\ /bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -g -fno-strict-aliasing -fwrapv -save-temps -Wall -fexceptions -MT src/ia64/ffi.lo -MD -MP -MF $depbase.Tpo -c -o src/ia64/ffi.lo ../src/ia64/ffi.c &&\ mv -f $depbase.Tpo $depbase.Plo libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I. -I../include -Iinclude -I../src -g -fno-strict-aliasing -fwrapv -save-temps -Wall -fexceptions -MT src/ia64/ffi.lo -MD -MP -MF src/ia64/.deps/ffi.Tpo -c ../src/ia64/ffi.c -fPIC -DPIC -o src/ia64/.libs/ffi.o ../src/ia64/ffi.c: In function 'ffi_prep_closure_loc': ../src/ia64/ffi.c:409:1: error: invalid types in nop conversion long long unsigned int void * D.3647 = (long long unsigned int) codeloc; ../src/ia64/ffi.c:409:1: internal compiler error: verify_gimple failed Please submit a full bug report, with preprocessed source if appropriate.
Compiled with checking enabled, obviously. With release checking the test case does not ICE, but I haven't checked the correctness of the resulting code.
Reduced test case: $ ./xgcc --version xgcc (GCC) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ $ $ ./xgcc -B. -S -v pr52611.i Reading specs from ./specs COLLECT_GCC=./xgcc COLLECT_LTO_WRAPPER=./lto-wrapper Target: ia64-hp-hpux11.31 Configured with: ../gcc-4.6.3/configure --with-mpfr=/opt/cfarm/mpfr-2.3.1 --with-gmp=/opt/cfarm/gmp-4.2.4 --with-mpc=/opt/cfarm/mpc-0.8 --enable-languages=c --disable-libmudflap --disable-libssp --disable-libitm --disable-lto --disable-bootstrap --target=ia64-hp-hpux11.31 --enable-checking Thread model: posix gcc version 4.6.3 (GCC) COLLECT_GCC_OPTIONS='-B' '.' '-S' '-v' ./cc1 -fpreprocessed pr52611.i -quiet -dumpbase pr52611.i -auxbase pr52611 -version -o pr52611.s GNU C (GCC) version 4.6.3 (ia64-hp-hpux11.31) compiled by GNU C version 4.3.2, GMP version 4.2.4, MPFR version 2.3.1, MPC version 0.8 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 GNU C (GCC) version 4.6.3 (ia64-hp-hpux11.31) compiled by GNU C version 4.3.2, GMP version 4.2.4, MPFR version 2.3.1, MPC version 0.8 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: b14f6f9b99e71d9e506f7502606725db pr52611.i: In function ‘foo’: pr52611.i:5:1: error: invalid types in nop conversion UINT64 void * D.1263 = (UINT64) x; pr52611.i:5:1: internal compiler error: verify_gimple failed Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. $ $ $ cat pr52611.i typedef void *PTR64 __attribute__((mode(DI))); typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); UINT64 foo (void *x) { return (UINT64)(PTR64)x; } I cannot reproduce this with trunk of today (r185505).
The problem happens very early on, during gimplification: #1 0x00000000009e7546 in verify_gimple_assign_unary (stmt=0x7ffff7fb5f00) at ../../gcc-4.6.3/gcc/tree-cfg.c:3241 3241 error ("invalid types in nop conversion"); (gdb) l 3236 3237 /* Otherwise assert we are converting between types of the 3238 same kind. */ 3239 if (INTEGRAL_TYPE_P (lhs_type) != INTEGRAL_TYPE_P (rhs1_type)) 3240 { 3241 error ("invalid types in nop conversion"); 3242 debug_generic_expr (lhs_type); 3243 debug_generic_expr (rhs1_type); 3244 return true; 3245 } (gdb) p debug_tree(lhs_type) <integer_type 0x7ffff7faa348 UINT64 unsigned DI size <integer_cst 0x7ffff7ec7a00 type <integer_type 0x7ffff7ee20a8 bit_size_type> constant 64> unit size <integer_cst 0x7ffff7ec7a28 type <integer_type 0x7ffff7ee2000 long unsigned int> constant 8> align 64 symtab 0 alias set -1 canonical type 0x7ffff7ee27e0 precision 64 min <integer_cst 0x7ffff7ec7a50 0> max <integer_cst 0x7ffff7ec79d8 18446744073709551615> context <translation_unit_decl 0x7ffff7eefda8 D.1262>> $7 = void (gdb) p debug_tree(rhs1_type) <pointer_type 0x7ffff7ee2f18 type <void_type 0x7ffff7ee2e70 void VOID align 8 symtab 0 alias set -1 canonical type 0x7ffff7ee2e70 pointer_to_this <pointer_type 0x7ffff7faa1f8>> public unsigned SI size <integer_cst 0x7ffff7ec7898 type <integer_type 0x7ffff7ee20a8 bit_size_type> constant 32> unit size <integer_cst 0x7ffff7ec75a0 type <integer_type 0x7ffff7ee2000 long unsigned int> constant 4> align 32 symtab 0 alias set -1 canonical type 0x7ffff7ee2f18 pointer_to_this <pointer_type 0x7ffff7ef8348> reference_to_this <reference_type 0x7ffff7ef6f18>> $8 = void (gdb) bt 10 #0 error (gmsgid=0xfe0890 "invalid types in nop conversion") at ../../gcc-4.6.3/gcc/diagnostic.c:751 #1 0x00000000009e7546 in verify_gimple_assign_unary (stmt=0x7ffff7fb5f00) at ../../gcc-4.6.3/gcc/tree-cfg.c:3241 #2 0x00000000009e9627 in verify_gimple_assign (stmt=0x7ffff7fb5f00) at ../../gcc-4.6.3/gcc/tree-cfg.c:3827 #3 0x00000000009e9c43 in verify_types_in_gimple_stmt (stmt=0x7ffff7fb5f00) at ../../gcc-4.6.3/gcc/tree-cfg.c:3984 #4 0x00000000009e9ea2 in verify_types_in_gimple_seq_2 (stmts=0x7ffff7fb4420) at ../../gcc-4.6.3/gcc/tree-cfg.c:4084 #5 0x00000000009ea096 in verify_types_in_gimple_seq (stmts=0x7ffff7fb4420) at ../../gcc-4.6.3/gcc/tree-cfg.c:4101 #6 0x0000000000820ec5 in gimplify_body (body_p=0x7ffff7fa9998, fndecl=0x7ffff7fa9900, do_parms=1 '\001') at ../../gcc-4.6.3/gcc/gimplify.c:7781 #7 0x000000000082155e in gimplify_function_tree (fndecl=0x7ffff7fa9900) at ../../gcc-4.6.3/gcc/gimplify.c:7870 #8 0x0000000000cb1eef in cgraph_analyze_function (node=0x7ffff7fc3000) at ../../gcc-4.6.3/gcc/cgraphunit.c:797 #9 0x0000000000cb2a90 in cgraph_analyze_functions () at ../../gcc-4.6.3/gcc/cgraphunit.c:983 (More stack frames follow...) (gdb) Note that void* seems to be of SImode, but the test case casts "void *x" to PTR64 which is a DImode pointer. Front end bug?
I don't think we should drop a cast that changes a machine mode: --- tree-ssa.c.orig 2012-03-18 17:32:32.000000000 +0100 +++ tree-ssa.c 2012-03-18 17:30:40.000000000 +0100 @@ -1264,6 +1264,10 @@ useless_type_conversion_p (tree outer_ty if (POINTER_TYPE_P (inner_type) && POINTER_TYPE_P (outer_type)) { + /* Do not lose casts between pointers in different machine modes. */ + if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)) + return false; + /* Do not lose casts between pointers to different address spaces. */ if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) GCC 4.7 and GCC 4.8 have a similar check in place.
(In reply to comment #4) > I don't think we should drop a cast that changes a machine mode: > > --- tree-ssa.c.orig 2012-03-18 17:32:32.000000000 +0100 > +++ tree-ssa.c 2012-03-18 17:30:40.000000000 +0100 > @@ -1264,6 +1264,10 @@ useless_type_conversion_p (tree outer_ty > if (POINTER_TYPE_P (inner_type) > && POINTER_TYPE_P (outer_type)) > { > + /* Do not lose casts between pointers in different machine modes. */ > + if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)) > + return false; > + > /* Do not lose casts between pointers to different address spaces. */ > if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) > != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) > > GCC 4.7 and GCC 4.8 have a similar check in place. Yes, the patch that introduced this can/should be backported.
Fixed in GCC 4.7.0 by r0-114570 (which removes the special case for void*).