re PR rtl-optimization/83608 (ICE in convert_move, at expr.c:229 in GIMPLE store...
authorJakub Jelinek <jakub@redhat.com>
Sun, 31 Dec 2017 23:52:01 +0000 (00:52 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sun, 31 Dec 2017 23:52:01 +0000 (00:52 +0100)
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.

From-SVN: r256053

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr83608.C [new file with mode: 0644]

index 98073e8f9427382001a339ea5c142e125c6e1a35..a0c9bf86bb5c9b8f66d363c896dcf370268c1846 100644 (file)
@@ -1,5 +1,10 @@
 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
index 0a735762e51da8e873e03f337d3090a56bb171ce..bae853c00ccfc679cb5feac462739323b3c243f4 100644 (file)
@@ -5638,8 +5638,21 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p,
   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
index 59c9543de5fa26a822e7e647381d3cbcfd372fbf..8b5c062e1f0687b14eb148648cebe99ea8f867a5 100644 (file)
@@ -1,5 +1,8 @@
 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.
diff --git a/gcc/testsuite/g++.dg/opt/pr83608.C b/gcc/testsuite/g++.dg/opt/pr83608.C
new file mode 100644 (file)
index 0000000..555e587
--- /dev/null
@@ -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> ();
+}