aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-11-20 09:32:56 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2019-11-20 09:32:56 +0100
commitd742b0c1a02aab7fa61b6d89eecee81b298f06c6 (patch)
tree27cfc00bd288f287714d449f817fefcce69e2c67 /gcc/expmed.c
parent94cdd3b7ceff688d039a9f134013ac9069df2e8c (diff)
downloadgcc-d742b0c1a02aab7fa61b6d89eecee81b298f06c6.zip
gcc-d742b0c1a02aab7fa61b6d89eecee81b298f06c6.tar.gz
gcc-d742b0c1a02aab7fa61b6d89eecee81b298f06c6.tar.bz2
re PR middle-end/90840 (ICE in simplify_subreg, at simplify-rtx.c:6441)
PR middle-end/90840 * expmed.c (store_bit_field_1): Handle the case where op0 is not a MEM and has a mode that doesn't have corresponding integral type. * gcc.c-torture/compile/pr90840.c: New test. From-SVN: r278483
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 512944e..a4a2556 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -840,6 +840,27 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
if (MEM_P (op0))
op0 = adjust_bitfield_address_size (op0, op0_mode.else_blk (),
0, MEM_SIZE (op0));
+ else if (!op0_mode.exists ())
+ {
+ if (ibitnum == 0
+ && known_eq (ibitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
+ && MEM_P (value)
+ && !reverse)
+ {
+ value = adjust_address (value, GET_MODE (op0), 0);
+ emit_move_insn (op0, value);
+ return true;
+ }
+ if (!fallback_p)
+ return false;
+ rtx temp = assign_stack_temp (GET_MODE (op0),
+ GET_MODE_SIZE (GET_MODE (op0)));
+ emit_move_insn (temp, op0);
+ store_bit_field_1 (temp, bitsize, bitnum, 0, 0, fieldmode, value,
+ reverse, fallback_p);
+ emit_move_insn (op0, temp);
+ return true;
+ }
else
op0 = gen_lowpart (op0_mode.require (), op0);
}