This PR is about a case in which we VIEW_CONVERT a variable-sized unaligned record:
<record_type 0x7ffff6d92888 check_displace_generation__T245b sizes-gimplified type_7 BLK size <var_decl 0x7ffff6846510 D.3499 ...> unit-size <var_decl 0x7ffff68465a0 D.3500 ...> align:8 ...> to an aligned 32-bit integer. The strict-alignment handling of this case creates an aligned temporary slot, moves the operand into the slot in the operand's original mode, then accesses the slot in the more-aligned result mode. Previously the size of the temporary slot was calculated using: HOST_WIDE_INT temp_size = MAX (int_size_in_bytes (inner_type), (HOST_WIDE_INT) GET_MODE_SIZE (mode)); int_size_in_bytes would return -1 for the variable-length type, so we'd use the size of the result mode for the slot. r256152 replaced int_size_in_bytes with tree_to_poly_uint64, which triggered an ICE. I'd assumed that variable-length types couldn't occur here, since it seems strange to view-convert a variable-length type to a fixed-length one. It also seemed strange that (with the old code) we'd ignore the size of the operand if it was a variable V but honour it if it was a constant C, even though it's presumably possible for V to equal that C at runtime. If op0 has BLKmode we do a block copy of GET_MODE_SIZE (mode) bytes and then convert the slot to "mode": poly_uint64 mode_size = GET_MODE_SIZE (mode); ... if (GET_MODE (op0) == BLKmode) { rtx size_rtx = gen_int_mode (mode_size, Pmode); emit_block_move (new_with_op0_mode, op0, size_rtx, (modifier == EXPAND_STACK_PARM ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL)); } else ... op0 = new_rtx; } } op0 = adjust_address (op0, mode, 0); so I think in that case just the size of "mode" is enough, even if op0 is a fixed-size type. For non-BLKmode op0 we first move in op0's mode and then convert the slot to "mode": emit_move_insn (new_with_op0_mode, op0); op0 = new_rtx; } } op0 = adjust_address (op0, mode, 0); so I think we want the maximum of the two mode sizes in that case (assuming they can be different sizes). But is this VIEW_CONVERT_EXPR really valid? Maybe this is just papering over a deeper issue. There again, the MAX in the old code was presumably there because the sizes can be different... Richard 2018-01-16 Richard Sandiford <richard.sandif...@linaro.org> gcc/ PR middle-end/83884 * expr.c (expand_expr_real_1): Use the size of GET_MODE (op0) rather than the size of inner_type to determine the stack slot size when handling VIEW_CONVERT_EXPRs on strict-alignment targets. Index: gcc/expr.c =================================================================== --- gcc/expr.c 2018-01-14 08:42:44.497155977 +0000 +++ gcc/expr.c 2018-01-16 16:07:22.737883774 +0000 @@ -11145,11 +11145,11 @@ expand_expr_real_1 (tree exp, rtx target } else if (STRICT_ALIGNMENT) { - tree inner_type = TREE_TYPE (treeop0); poly_uint64 mode_size = GET_MODE_SIZE (mode); - poly_uint64 op0_size - = tree_to_poly_uint64 (TYPE_SIZE_UNIT (inner_type)); - poly_int64 temp_size = upper_bound (op0_size, mode_size); + poly_uint64 temp_size = mode_size; + if (GET_MODE (op0) != BLKmode) + temp_size = upper_bound (temp_size, + GET_MODE_SIZE (GET_MODE (op0))); rtx new_rtx = assign_stack_temp_for_type (mode, temp_size, type); rtx new_with_op0_mode