re PR bootstrap/41031 (ICE in insert_value_copy_on_edge preventing bootstrap on sparc...
[gcc.git] / gcc / tree-outof-ssa.c
index 420ee8099b4445402c16b499ba6268d7d84d6ea1..220171ca7f9dd6d8df89a74a0dfd8a6cfbba483d 100644 (file)
@@ -195,7 +195,10 @@ static void
 insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
 {
   rtx seq, x;
-  enum machine_mode mode;
+  enum machine_mode dest_mode, src_mode;
+  int unsignedp;
+  tree var;
+
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file,
@@ -214,14 +217,22 @@ insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
     set_curr_insn_source_location (locus);
 
   start_sequence ();
-  mode = GET_MODE (SA.partition_to_pseudo[dest]);
-  x = expand_expr (src, SA.partition_to_pseudo[dest], mode, EXPAND_NORMAL);
-  if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode)
-    x = convert_to_mode (mode, x, TYPE_UNSIGNED (TREE_TYPE (src)));
-  if (CONSTANT_P (x) && GET_MODE (x) == VOIDmode
-      && mode != TYPE_MODE (TREE_TYPE (src)))
-    x = convert_modes (mode, TYPE_MODE (TREE_TYPE (src)),
-                         x, TYPE_UNSIGNED (TREE_TYPE (src)));
+
+  var = SSA_NAME_VAR (partition_to_var (SA.map, dest));
+  src_mode = TYPE_MODE (TREE_TYPE (src));
+  dest_mode = promote_decl_mode (var, &unsignedp);
+  gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (var)));
+  gcc_assert (dest_mode == GET_MODE (SA.partition_to_pseudo[dest]));
+
+  if (src_mode != dest_mode)
+    {
+      x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
+      x = convert_modes (dest_mode, src_mode, x, unsignedp);
+    }
+  else
+    x = expand_expr (src, SA.partition_to_pseudo[dest],
+                    dest_mode, EXPAND_NORMAL);
+
   if (x != SA.partition_to_pseudo[dest])
     emit_move_insn (SA.partition_to_pseudo[dest], x);
   seq = get_insns ();