aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-17 09:28:28 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-17 09:28:28 +0000
commitac9335bfed00633ad26eb0ec62bbdb54cdaf0429 (patch)
tree77e6465443a70b5a8698784acbc82b3c64b0bb33 /gcc/expr.c
parent67f40e182c78353bfeac90e776e194833659d139 (diff)
downloadgcc-ac9335bfed00633ad26eb0ec62bbdb54cdaf0429.zip
gcc-ac9335bfed00633ad26eb0ec62bbdb54cdaf0429.tar.gz
gcc-ac9335bfed00633ad26eb0ec62bbdb54cdaf0429.tar.bz2
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: <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. 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 <richard.sandiford@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. From-SVN: r256779
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c8
1 files changed, 4 insertions, 4 deletions
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