On Tue, Jul 7, 2015 at 2:35 PM, Richard Biener <richard.guent...@gmail.com> wrote: > On July 7, 2015 6:29:21 PM GMT+02:00, Jim Wilson <jim.wil...@linaro.org> > wrote: >>signed sub-word locals. Thus to detect the need for a conversion, you >>have to have the decls, and we don't have them here. There is also > > It probably is. The decks for the parameter based SSA names are available, > for the PHI destination there might be no decl.
I tried looking again, and found the decls. I'm able to get correct code for my testcase with the attached patch to force the conversion. It is rather inelegant, but I think I can cache the values I need to make this simpler and cleaner. I still don't have decls from insert_part_to_rtx_on_edge and insert_rtx_to_part_on_edge, but it looks like those are for breaking cycles, and hence might not need conversions. Jim
Index: tree-outof-ssa.c =================================================================== --- tree-outof-ssa.c (revision 225477) +++ tree-outof-ssa.c (working copy) @@ -230,11 +230,32 @@ set_location_for_edge (edge e) SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from which we deduce the size to copy in that case. */ -static inline rtx_insn * -emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp) +rtx_insn * +emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp, + tree var2 ATTRIBUTE_UNUSED) { start_sequence (); + /* If var2 is set, then sizeexp is the src decl and var2 is the dest decl. */ + if (var2) + { + tree src_var = (TREE_CODE (sizeexp) == SSA_NAME + ? SSA_NAME_VAR (sizeexp) : sizeexp); + tree dest_var = (TREE_CODE (var2) == SSA_NAME + ? SSA_NAME_VAR (var2) : var2); + int src_unsignedp = TYPE_UNSIGNED (TREE_TYPE (src_var)); + int dest_unsignedp = TYPE_UNSIGNED (TREE_TYPE (dest_var)); + machine_mode src_mode = promote_decl_mode (src_var, &src_unsignedp); + machine_mode dest_mode = promote_decl_mode (dest_var, &dest_unsignedp); + if (src_unsignedp != dest_unsignedp + && src_mode != DECL_MODE (src_var) + && dest_mode != DECL_MODE (dest_var)) + { + src = gen_lowpart_common (DECL_MODE (src_var), src); + unsignedsrcp = dest_unsignedp; + } + } + if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest)) src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp); if (GET_MODE (src) == BLKmode) @@ -256,7 +277,7 @@ emit_partition_copy (rtx dest, rtx src, static void insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) { - tree var; + tree var, var2; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, @@ -276,10 +297,11 @@ insert_partition_copy_on_edge (edge e, i set_curr_insn_location (locus); var = partition_to_var (SA.map, src); + var2 = partition_to_var (SA.map, dest); rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), copy_rtx (SA.partition_to_pseudo[src]), TYPE_UNSIGNED (TREE_TYPE (var)), - var); + var, var2); insert_insn_on_edge (seq, e); } @@ -373,7 +395,8 @@ insert_rtx_to_part_on_edge (edge e, int involved), so it doesn't matter. */ rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), src, unsignedsrcp, - partition_to_var (SA.map, dest)); + partition_to_var (SA.map, dest), 0); + insert_insn_on_edge (seq, e); } @@ -406,7 +429,7 @@ insert_part_to_rtx_on_edge (edge e, rtx rtx_insn *seq = emit_partition_copy (dest, copy_rtx (SA.partition_to_pseudo[src]), TYPE_UNSIGNED (TREE_TYPE (var)), - var); + var, 0); insert_insn_on_edge (seq, e); }