re PR middle-end/90840 (ICE in simplify_subreg, at simplify-rtx.c:6441)
authorJakub Jelinek <jakub@redhat.com>
Wed, 20 Nov 2019 08:32:56 +0000 (09:32 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 20 Nov 2019 08:32:56 +0000 (09:32 +0100)
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

gcc/ChangeLog
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr90840.c [new file with mode: 0644]

index 32af46773934c10087dea8ddf94853d43edfa405..f350d36167a0d66c7c96d55cc2dfd8b5fb06b8a7 100644 (file)
@@ -1,5 +1,9 @@
 2019-11-20  Jakub Jelinek  <jakub@redhat.com>
 
+       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.
+
        PR target/90867
        * config/i386/i386-options.c (ix86_valid_target_attribute_tree): Don't
        clear opts->x_ix86_isa_flags{,2} here...
index 512944ef418348b9dc50684b9f085c23206f9d8b..a4a25560df6e77ea3e748a3663c0552d22c4206a 100644 (file)
@@ -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);
     }
index e199f4c62142f4e1c52f2fc399d578916624bd70..7de7a43dc41b4018de226ab5c54ee38a6468817a 100644 (file)
@@ -1,5 +1,8 @@
 2019-11-20  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/90840
+       * gcc.c-torture/compile/pr90840.c: New test.
+
        PR target/90867
        * gcc.target/i386/pr90867.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr90840.c b/gcc/testsuite/gcc.c-torture/compile/pr90840.c
new file mode 100644 (file)
index 0000000..94a6f3f
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR middle-end/90840 */
+struct S { long long a; int b; };
+struct S foo (void);
+struct __attribute__((packed)) T { long long a; char b; };
+struct T baz (void);
+
+void
+bar (void)
+{
+  _Complex long double c;
+  *(struct S *) &c = foo ();
+}
+
+void
+qux (void)
+{
+  _Complex long double c;
+  *(struct T *) &c = baz ();
+}