> On Thu, 8 Oct 2015, Jan Hubicka wrote: > > > > > > > && TREE_CODE (outer_type) == OFFSET_TYPE > > > > > > Ok with those changes. > > > > Thank you! I commited the patch. > > At a hike today it appeared to me that for ipa-icf and other calling > > convetions > > checks we should not rely on useless_type_conversion_p because there may be > > types that are compatible in gimple type system but have different calling > > conventions. I will hack calling convention comparer tomorrow - should not > > be > > too hard, just doing the cumulative walk and comparing that the RTL > > containers > > are the same. > > I think the patch caused a bootstrap failure on x86_64-linux with Ada. > We're having an aggregate copy SImode = BLKmode and end up with > BLKmode from int_mode_for_mode (BLKmode) which later ICEs (obviously) > in gen_lowpart.
Yep, there is pre-existing code to go from BLKmode to normal mode at store field. else if (mode == BLKmode) { /* Handle calls that return BLKmode values in registers. */ if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR) { rtx temp_target = gen_reg_rtx (GET_MODE (temp)); copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp)); temp = temp_target; } else { HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); rtx temp_target; mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); temp_target = gen_reg_rtx (mode); temp_target = extract_bit_field (temp, size * BITS_PER_UNIT, 0, 1, temp_target, mode, mode); temp = temp_target; } } /* Store the value in the bitfield. */ Problem here is that the EXP is schizofrenic: (gdb) p debug_tree (exp) <component_ref 0x7ffff628ec90 type <record_type 0x7ffff6988c78 system__regpat__expression_flags sizes-gimplified asm_written SI size <integer_cst 0x7ffff6ecedf8 constant 32> unit size <integer_cst 0x7ffff6ecee10 constant 4> user align 32 symtab -169633040 alias set 12 canonical type 0x7ffff6988c78 fields <field_decl 0x7ffff69895f0 has_width type <boolean_type 0x7ffff6eecdc8 boolean> unsigned nonaddressable QI file s-regpat.adb line 1013 col 19 size <integer_cst 0x7ffff6ececa8 constant 8> unit size <integer_cst 0x7ffff6ececc0 constant 1> align 8 offset_align 128 offset <integer_cst 0x7ffff6ecebe8 constant 0> bit offset <integer_cst 0x7ffff6ecec30 constant 0> context <record_type 0x7ffff6988c78 system__regpat__expression_flags> original field <field_decl 0x7ffff6942980 has_width> chain <field_decl 0x7ffff6989688 simple>> Ada size <integer_cst 0x7ffff6eeb060 constant 24> chain <type_decl 0x7ffff69897b8 system__regpat__expression_flags>> arg 0 <var_decl 0x7ffff65f37e0 new_flags type <record_type 0x7ffff6988bd0 system__regpat__compile__parse_atom__2__B_8__new_flags___PAD sizes-gimplified asm_written type_5 SI size <integer_cst 0x7ffff6ecedf8 32> unit size <integer_cst 0x7ffff6ecee10 4> align 32 symtab -169633120 alias set -1 canonical type 0x7ffff6988bd0 fields <field_decl 0x7ffff6989850 F> context <function_decl 0x7ffff695fc40 system__regpat__compile__parse_atom__2> Ada size <integer_cst 0x7ffff6eeb060 24> pointer_to_this <pointer_type 0x7ffff6aa33f0> chain <type_decl 0x7ffff69898e8 system__regpat__compile__parse_atom__2__B_8__new_flags___PAD>> used SI file s-regpat.adb line 1013 col 19 size <integer_cst 0x7ffff6ecedf8 32> unit size <integer_cst 0x7ffff6ecee10 4> align 32 context <function_decl 0x7ffff695fa80 system__regpat__compile__parse_branch__2> abstract_origin <var_decl 0x7ffff69863f0 new_flags> (reg/v:SI 1546 [ new_flags ])> arg 1 <field_decl 0x7ffff6989850 F type <record_type 0x7ffff6988c78 system__regpat__expression_flags> external packed bit-field nonaddressable decl_3 SI file s-regpat.adb line 1013 col 19 size <integer_cst 0x7ffff6eeb060 24> unit size <integer_cst 0x7ffff6eeb840 constant 3> align 1 offset_align 128 offset <integer_cst 0x7ffff6ecebe8 0> bit offset <integer_cst 0x7ffff6ecec30 0> bit_field_type <record_type 0x7ffff6988c78 system__regpat__expression_flags> context <record_type 0x7ffff6988bd0 system__regpat__compile__parse_atom__2__B_8__new_flags___PAD>>> The type has BLKmode and size 32. DECL_SIZE of the FIELD_DECL is however 24 (see it printed as Ada size). The DECL_MODE of the FIELD_DECL is VOIDmode (not printed), while the TYPE_MODE of type contained is BLKmode. Because get_inner_reference compute mode based on DECL_MODE: if (TREE_CODE (exp) == COMPONENT_REF) { tree field = TREE_OPERAND (exp, 1); size_tree = DECL_SIZE (field); if (flag_strict_volatile_bitfields > 0 && TREE_THIS_VOLATILE (exp) && DECL_BIT_FIELD_TYPE (field) && DECL_MODE (field) != BLKmode) /* Volatile bitfields should be accessed in the mode of the field's type, not the mode computed based on the bit size. */ mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field)); else if (!DECL_BIT_FIELD (field)) mode = DECL_MODE (field); else if (DECL_MODE (field) == BLKmode) blkmode_bitfield = true; *punsignedp = DECL_UNSIGNED (field); } We miss the check else if (mode == BLKmode) and fail to convert the register and die in horrible death. What is the reason behind this construct? Is that Ada bug? Anyway, the following patch fixes the issue by caring about mode of the temporary (which is controled by the type) instead of the mode of the field. I am testing it on x86_64-linux now. Honza Index: expr.c =================================================================== --- expr.c (revision 228604) +++ expr.c (working copy) @@ -6703,7 +6704,7 @@ store_field (rtx target, HOST_WIDE_INT b emit_group_store (temp_target, temp, TREE_TYPE (exp), size); temp = temp_target; } - else if (mode == BLKmode) + else if (GET_MODE (temp) == BLKmode) { /* Handle calls that return BLKmode values in registers. */ if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)