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...
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);
}
--- /dev/null
+/* 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 ();
+}