2018-01-01 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/83608
+ * expr.c (store_expr_with_bounds): Use simplify_gen_subreg instead of
+ convert_modes if target mode has the right side, but different mode
+ class.
+
PR middle-end/83609
* expr.c (expand_assignment): Fix up a typo in simplify_gen_subreg
last argument when extracting from CONCAT. If either from_real or
if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
&& TREE_CODE (exp) != ERROR_MARK
&& GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
- temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
- temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
+ {
+ if (GET_MODE_CLASS (GET_MODE (target))
+ != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
+ && GET_MODE_BITSIZE (GET_MODE (target))
+ == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp))))
+ {
+ rtx t = simplify_gen_subreg (GET_MODE (target), temp,
+ TYPE_MODE (TREE_TYPE (exp)), 0);
+ if (t)
+ temp = t;
+ }
+ if (GET_MODE (temp) == VOIDmode)
+ temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
+ temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
+ }
/* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if necessary and emit the
2018-01-01 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/83608
+ * g++.dg/opt/pr83608.C: New test.
+
PR middle-end/83609
* gcc.dg/pr83609.c: New test.
* g++.dg/opt/pr83609.C: New test.
--- /dev/null
+// PR middle-end/83608
+// { dg-do compile }
+// { dg-options "-O2" }
+
+template <typename> class B;
+template <> struct B<float>
+{
+ float foo () { return __real__ b; }
+ _Complex double b;
+};
+
+void bar (int);
+
+template <class T>
+void
+baz ()
+{
+ B<T> h;
+ T *a = (T *) &h;
+ a[0] = a[1] = 6;
+ h.foo () ? void () : bar (7);
+}
+
+int
+main ()
+{
+ baz<float> ();
+}