On December 30, 2017 8:35:09 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>The comment on convert_modes says:
>   Both modes may be floating, or both integer.
>but as the testcase shows, with a MEM_REF with a different mode class
>than a VAR_DECL as its operand we can end up with e.g. floating point
>vs.
>integral mode etc. and convert_modes doesn't handle those cases.
>
>This patch uses simplify_gen_subreg in those case first.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
>trunk/7.3?

OK. 

Richard. 

>2017-12-30  Jakub Jelinek  <ja...@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.
>
>       * g++.dg/opt/pr83608.C: New test.
>
>--- gcc/expr.c.jj      2017-12-30 14:35:52.095877981 +0100
>+++ gcc/expr.c 2017-12-30 14:36:06.268882813 +0100
>@@ -5638,8 +5638,21 @@ store_expr_with_bounds (tree exp, rtx ta
>   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
>--- gcc/testsuite/g++.dg/opt/pr83608.C.jj      2017-12-30 14:36:52.323898522
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr83608.C 2017-12-30 14:00:12.811195532
>+0100
>@@ -0,0 +1,28 @@
>+// 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> ();
>+}
>
>       Jakub

Reply via email to