fwprop.c (forward_propagate_subreg): Skip the SIGN/ZERO_EXTEND optimization if the source register is already extended.

gcc/
	* fwprop.c (forward_propagate_subreg): Skip the SIGN/ZERO_EXTEND
	optimization if the source register is already extended.

From-SVN: r182504
This commit is contained in:
Richard Sandiford 2011-12-19 22:05:28 +00:00 committed by Richard Sandiford
parent 373203331a
commit 7a61392921
2 changed files with 19 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2011-12-19 Richard Sandiford <rdsandiford@googlemail.com>
* fwprop.c (forward_propagate_subreg): Skip the SIGN/ZERO_EXTEND
optimization if the source register is already extended.
2011-12-19 Richard Sandiford <rdsandiford@googlemail.com> 2011-12-19 Richard Sandiford <rdsandiford@googlemail.com>
* lower-subreg.c (can_decompose_p): Check every word of a hard * lower-subreg.c (can_decompose_p): Check every word of a hard

View File

@ -1112,7 +1112,18 @@ forward_propagate_subreg (df_ref use, rtx def_insn, rtx def_set)
/* If this is a SUBREG of a ZERO_EXTEND or SIGN_EXTEND, and the SUBREG /* If this is a SUBREG of a ZERO_EXTEND or SIGN_EXTEND, and the SUBREG
is the low part of the reg being extended then just use the inner is the low part of the reg being extended then just use the inner
operand. Don't do this if the ZERO_EXTEND or SIGN_EXTEND insn will operand. Don't do this if the ZERO_EXTEND or SIGN_EXTEND insn will
be removed due to it matching a LOAD_EXTEND_OP load from memory. */ be removed due to it matching a LOAD_EXTEND_OP load from memory,
or due to the operation being a no-op when applied to registers.
For example, if we have:
A: (set (reg:DI X) (sign_extend:DI (reg:SI Y)))
B: (... (subreg:SI (reg:DI X)) ...)
and mode_rep_extended says that Y is already sign-extended,
the backend will typically allow A to be combined with the
definition of Y or, failing that, allow A to be deleted after
reload through register tying. Introducing more uses of Y
prevents both optimisations. */
else if (subreg_lowpart_p (use_reg)) else if (subreg_lowpart_p (use_reg))
{ {
use_insn = DF_REF_INSN (use); use_insn = DF_REF_INSN (use);
@ -1123,6 +1134,8 @@ forward_propagate_subreg (df_ref use, rtx def_insn, rtx def_set)
&& REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
&& GET_MODE (XEXP (src, 0)) == use_mode && GET_MODE (XEXP (src, 0)) == use_mode
&& !free_load_extend (src, def_insn) && !free_load_extend (src, def_insn)
&& (targetm.mode_rep_extended (use_mode, GET_MODE (src))
!= (int) GET_CODE (src))
&& all_uses_available_at (def_insn, use_insn)) && all_uses_available_at (def_insn, use_insn))
return try_fwprop_subst (use, DF_REF_LOC (use), XEXP (src, 0), return try_fwprop_subst (use, DF_REF_LOC (use), XEXP (src, 0),
def_insn, false); def_insn, false);