https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64111
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Target Milestone|--- |5.0 --- Comment #17 from Richard Biener <rguenth at gcc dot gnu.org> --- <view_convert_expr 0x7ffff6836660 type <vector_type 0x10001e8608 type <integer_type 0x10001dedc8 long long int DI size <integer_cst 0x100000eb00 constant 64> unit size <integer_cst 0x100000eb20 constant 8> align 64 symtab 0 alias set -1 canonical type 0x10001dedc8 precision 64 min <integer_cst 0x1000010b40 -9223372036854775808> max <integer_cst 0x1000010b60 9223372036854775807> pointer_to_this <pointer_type 0x10001e5a10>> V4DI size <integer_cst 0x1000010d40 constant 256> unit size <integer_cst 0x1000010d80 constant 32> align 256 symtab 0 alias set -1 canonical type 0x10001e86b0 nunits 4 pointer_to_this <pointer_type 0x10001e8758>> arg 0 <ssa_name 0x7ffff68830d8 type <vector_type 0x7ffff686a000 type <integer_type 0x10001ded20 long unsigned int> unsigned V4DI size <integer_cst 0x7ffff6851de0 constant 256> unit size <integer_cst 0x1000010d80 32> align 256 symtab 0 alias set 6 canonical type 0x7ffff686a000 nunits 4 pointer_to_this <pointer_type 0x7ffff6870690>> var <var_decl 0x7ffff68825f0 vect_var_.22>def_stmt vect_var_.22_70 = MEM[(struct QAbstractAnimationTimer * const &)vect_ppretmp.18_68]; version 70>> It looks like PCH causes integer constant sharing to break down. (gdb) p debug_tree ((tree)0x7ffff6851de0) <integer_cst 0x7ffff6851de0 type <integer_type 0x10001de690 bitsizetype> constant 256> $2 = void (gdb) p debug_tree ((tree)0x1000010d40) <integer_cst 0x1000010d40 type <integer_type 0x10001de690 bitsizetype> constant 256> the constant is above the integer share limit thus it only gets shared via the int_cst_hash_table hashtable which is collectible: static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) htab_t int_cst_hash_table; but we are supposed to save that into the PCH file and restore it. tree-cfg.c relies on this: else if (TREE_CODE (op) == SSA_NAME && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op))) { error ("conversion of register to a different size"); though from a quick grep it doesn't seem to be the only one doing so: fold-const.c: return ((TYPE_SIZE (TREE_TYPE (arg0)) == TYPE_SIZE (TREE_TYPE (arg1)) tree-inline.c: gcc_checking_assert (TYPE_SIZE (type) == TYPE_SIZE (TYPE_MAIN_VARIANT (type))); tree-inline.c: gcc_checking_assert (TYPE_SIZE_UNIT (type) == TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))); tree-inline.c: || TYPE_SIZE (TREE_TYPE (p)) == TYPE_SIZE (TREE_TYPE (value))) tree-inline.c: else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (replace_info->new_tree))) Ah, the issue might be that we have (on the 4.8 branch): /* Return the hash code code X, an INTEGER_CST. */ static hashval_t int_cst_hash_hash (const void *x) { const_tree const t = (const_tree) x; return (TREE_INT_CST_HIGH (t) ^ TREE_INT_CST_LOW (t) ^ htab_hash_pointer (TREE_TYPE (t))); } thus we hash in the pointer value ... (oops). Similar on trunk: /* Return the hash code code X, an INTEGER_CST. */ hashval_t int_cst_hasher::hash (tree x) { const_tree const t = x; hashval_t code = htab_hash_pointer (TREE_TYPE (t)); int i; for (i = 0; i < TREE_INT_CST_NUNITS (t); i++) code ^= TREE_INT_CST_ELT (t, i); return code; } I'm quite sure that doesn't survive pointer-swizzling with PCH. I suggest to use a better hash than a simple XOR and rather than hashing in TREE_TYPE hash in TYPE_UID.