Fix expand_expr_real_1 handling of BLKmode bitfield references

Programming / Compilers / GCC - rsandifo [138bc75d-0d04-0410-961f-82ee72b054a4] - 4 June 2018 15:02 EDT

The handling of bitfield references in expand_expr_real_1 includes:

machine_mode ext_mode = mode;

if (ext_mode == BLKmode && ! (target != 0 && MEM_P (op0) && MEM_P (target) && multiple_p (bitpos, BITS_PER_UNIT))) ext_mode = int_mode_for_size (bitsize, 1).else_blk ();

if (ext_mode == BLKmode) { [...] gcc_assert (MEM_P (op0)

Here "mode" is the TYPE_MODE of the result, so when mode == BLKmode, the target must be a MEM if nonnull, since no other rtl objects can have BLKmode. But there's no guarantee that the source value op0 is also BLKmode and thus also a MEM: we can reach the assert for any source if the bitsize being extracted is larger than the largest integer mode (or larger than MAX_FIXED_MODE_SIZE).

This triggered for SVE with -msve-vector-bits=512, where we could sometimes try to extract a BLKmode value from a 512-bit vector, and where int_mode_for_size would rightly fail for large bitsizes.

The patch reuses the existing:

/* Otherwise, if this is a constant or the object is not in memory and need be, put it there. */ else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem)) { memloc = assign_temp (TREE_TYPE (tem), 1, 1); emit_move_insn (memloc, op0); op0 = memloc; clear_mem_expr = true; }

to handle this case.

2018-05-29 Richard Sandiford

gcc/
- expr.c (expand_expr_real_1): Force the operand into memory if its TYPE_MODE is BLKmode and if there is no integer mode for the number of bits being extracted.

gcc/testsuite/
- gcc.target/aarch64/sve/extract_5.c: New test.

5228d413970 Fix expand_expr_real_1 handling of BLKmode bitfield references
gcc/ChangeLog | 6 ++
gcc/expr.c | 2 +
gcc/testsuite/ChangeLog | 4 ++
gcc/testsuite/gcc.target/aarch64/sve/extract_5.c | 71 ++++++++++++++++++++++++
4 files changed, 83 insertions(+)

Upstream: gcc.gnu.org


  • Share