[Sorry for the delay]

> For example, when an expression is evaluated and it's value is assigned
> to variable of type short, the generated RTL would look something like
> the following.
> 
> (set (reg:SI 110)
>                   (zero_extend:SI (subreg:HI (reg:SI 117) 0)))
> 
> However, if during value range propagation, if we can say for certain
> that the value of the expression which is present in register 117 is
> within the limits of short and there is no sign conversion, we do not
> need to perform the subreg and zero_extend; instead we can generate the
> following RTl.
> 
> (set (reg:SI 110)
>                   (reg:SI 117)))
> 
> Same could be done for other assign statements.

The idea looks interesting.  Some remarks:

> +2013-06-03  Kugan Vivekanandarajah  <kug...@linaro.org>
> +
> +     * gcc/dojump.c (do_compare_and_jump): generates rtl without
> +     zero/sign extension if redundant.
> +     * gcc/cfgexpand.c (expand_gimple_stmt_1): Likewise.
> +     * gcc/gimple.c (gimple_assign_is_zero_sign_ext_redundant) : New
> +     function.
> +     * gcc/gimple.h (gimple_assign_is_zero_sign_ext_redundant) : New
> +     function definition.

No gcc/ prefix in entries for gcc/ChangeLog.  "Generate RTL without..."


+            /* If the value in SUBREG of temp fits that SUBREG (does not
+               overflow) and is assigned to target SUBREG of the same mode
+               without sign convertion, we can skip the SUBREG
+               and extension.  */
+            else if (promoted
+                     && gimple_assign_is_zero_sign_ext_redundant (stmt)
+                     && (GET_CODE (temp) == SUBREG)
+                     && (GET_MODE (target) == GET_MODE (temp))
+                     && (GET_MODE (SUBREG_REG (target))
+                         == GET_MODE (SUBREG_REG (temp))))
+             emit_move_insn (SUBREG_REG (target), SUBREG_REG (temp));
            else if (promoted)
              {
                int unsignedp = SUBREG_PROMOTED_UNSIGNED_P (target);

Can we relax the strict mode equality here?  This change augments the same 
transformation applied to the RHS when it is also a SUBREG_PROMOTED_VAR_P at 
the beginning of convert_move, but the condition on the mode is less strict in 
the latter case, so maybe it can serve as a model here.


+  /* Is zero/sign extension redundant as per VRP.  */
+  bool op0_ext_redundant = false;
+  bool op1_ext_redundant = false;
+
+  /* If promoted and the value in SUBREG of op0 fits (does not overflow),
+     it is a candidate for extension elimination.  */
+  if (GET_CODE (op0) == SUBREG && SUBREG_PROMOTED_VAR_P (op0))
+    op0_ext_redundant =
+      gimple_assign_is_zero_sign_ext_redundant (SSA_NAME_DEF_STMT (treeop0));
+
+  /* If promoted and the value in SUBREG of op1 fits (does not overflow),
+     it is a candidate for extension elimination.  */
+  if (GET_CODE (op1) == SUBREG && SUBREG_PROMOTED_VAR_P (op1))
+    op1_ext_redundant =
+      gimple_assign_is_zero_sign_ext_redundant (SSA_NAME_DEF_STMT (treeop1));

Are the gimple_assign_is_zero_sign_ext_redundant checks necessary here?  
When set on a SUBREG, SUBREG_PROMOTED_VAR_P guarantees that SUBREG_REG is 
always properly extended (otherwise it's a bug) so don't you just need to 
compare SUBREG_PROMOTED_UNSIGNED_SET?  See do_jump for an existing case.


+  /* If zero/sign extension is redundant, generate RTL
+     for operands without zero/sign extension.  */
+  if ((op0_ext_redundant || TREE_CODE (treeop0) == INTEGER_CST)
+      && (op1_ext_redundant || TREE_CODE (treeop1) == INTEGER_CST))

Don't you need to be careful with the INTEGER_CSTs here?  The CONST_INTs are 
always sign-extended in RTL so 0x80 is always represented by (const_int -128) 
in QImode, whatever the signedness.  If SUBREG_PROMOTED_UNSIGNED_SET is true,
then comparing in QImode and comparing in e.g. SImode wouldn't be equivalent.

-- 
Eric Botcazou

Reply via email to