aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-06-04 15:02:07 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-06-04 15:02:07 +0000
commit8566678b9da3db996f7566ecb691be07ff376c8f (patch)
tree140b2b6b07bda90ed0314c7223b1b643c120011a /gcc/expr.c
parent1fc9aa543f41a1485187c96806950795a7966974 (diff)
downloadgcc-8566678b9da3db996f7566ecb691be07ff376c8f.zip
gcc-8566678b9da3db996f7566ecb691be07ff376c8f.tar.gz
gcc-8566678b9da3db996f7566ecb691be07ff376c8f.tar.bz2
Fix expand_expr_real_1 handling of BLKmode bitfield references
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 <richard.sandiford@linaro.org> 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. From-SVN: r261150
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 1fa3227..f15037a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10579,6 +10579,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
to a larger size. */
must_force_mem = (offset
|| mode1 == BLKmode
+ || (mode == BLKmode
+ && !int_mode_for_size (bitsize, 1).exists ())
|| maybe_gt (bitpos + bitsize,
GET_MODE_BITSIZE (mode2)));