From ac9335bfed00633ad26eb0ec62bbdb54cdaf0429 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 17 Jan 2018 09:28:28 +0000 Subject: [PATCH] VIEW_CONVERT_EXPR slots for strict-align targets (PR 83884) This PR is about a case in which we VIEW_CONVERT a variable-sized unaligned record: unit-size 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. 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. 2018-01-17 Richard Sandiford 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. From-SVN: r256779 --- gcc/ChangeLog | 7 +++++++ gcc/expr.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f83eb6..4c51987 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-01-17 Richard Sandiford + + 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. + 2018-01-16 Sebastian Peryt PR target/83546 diff --git a/gcc/expr.c b/gcc/expr.c index 42f889f..36a6c72 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -11145,11 +11145,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, } 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 -- 2.7.4