https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932

--- Comment #12 from Jim Wilson <wilson at gcc dot gnu.org> ---
Part of the problem here is that the arm port defines PROMOTE_MODE to force
short local variables to unsigned, but arm_promote_function_mode doesn't change
signedness.  So a signed short parameter and a signed short local have
different representations in a register.

Another part of the problem is that the eipa_sra pass is creating phi nodes
that mix parameters and local variables.  Copying a signed short local into a
signed short parameter requires a conversion, even though they have the same
type, because they get different in register promotion.

Another part of the problem is that the out-of-ssa pass when evaluating phi
nodes doesn't go through expand_expr, and hence doesn't handle mode promotion. 
The code is copying DECL_RTL directly into SA.partition_to_pseudo, and then
using SA.partition_to_pseudo when emitting the copy instructions.  Thus these
phi nodes won't emit any conversion instructions even though one is apparently
required.

I can get correct code if I pass DECL_RTL through expand_expr before storing it
into SA.partition_to_pseudo for VAR_DECLs.  However, if I then do the same
thing for PARM_DECLS, then I get a movhi insn instead of a conversion, because
both the source and dest are promoted subregs.  I think the problem here is
that emit_partition_copy doesn't handle promoted subregs.  I think we need
something like what store_expr_with_bounds does, when the dest is a promoted
subreg, to do the copy to the smaller mode, and then convert to the wider mode.
 But I have a few too many suppositions at this point and am not sure if this
makes sense.

It might be simpler to change the arm port so that promote_mode and
function_promote_mode match.

Reply via email to