diff mbox

[RFC,3/3] Enable zero/sign extension elimination

Message ID 55381D7E.2000106@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah April 22, 2015, 10:15 p.m. UTC
On 17/01/15 13:11, Kugan wrote:
> 
> Re-enable zero/sign extension elimination using value range that
> includes wrapped attribute.
> 

Now that stage-1 is open, rebased it and regression tested on
x86-64-none-linux-gnu with no new regressions.

Is this OK for trunk?

Thanks,
Kugan

gcc/ChangeLog:

2015-04-22  Kugan Vivekanandarajah  <kuganv@linaro.org>

	* calls.c (precompute_arguments): Check
	 promoted_for_signed_and_unsigned_p and set the promoted mode.
	* expr.c (expand_expr_real_1): Likewise.
	(promoted_for_signed_and_unsigned_p): New function.
	* cfgexpand.c (expand_gimple_stmt_1): Call emit_move_insn if
	SUBREG is promoted with SRP_SIGNED_AND_UNSIGNED.
	* expr.h (promoted_for_signed_and_unsigned_p): New definition.

Comments

Kugan Vivekanandarajah April 22, 2015, 11:54 p.m. UTC | #1
On 23/04/15 09:48, H.J. Lu wrote:
> On Wed, Apr 22, 2015 at 3:15 PM, Kugan
> <kugan.vivekanandarajah@linaro.org> wrote:
>> On 17/01/15 13:11, Kugan wrote:
>>>
>>> Re-enable zero/sign extension elimination using value range that
>>> includes wrapped attribute.
>>>
>>
>> Now that stage-1 is open, rebased it and regression tested on
>> x86-64-none-linux-gnu with no new regressions.
>>
>> Is this OK for trunk?
>>
>> Thanks,
>> Kugan
>>
>> gcc/ChangeLog:
>>
>> 2015-04-22  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>
>>         * calls.c (precompute_arguments): Check
>>          promoted_for_signed_and_unsigned_p and set the promoted mode.
>>         * expr.c (expand_expr_real_1): Likewise.
>>         (promoted_for_signed_and_unsigned_p): New function.
>>         * cfgexpand.c (expand_gimple_stmt_1): Call emit_move_insn if
>>         SUBREG is promoted with SRP_SIGNED_AND_UNSIGNED.
>>         * expr.h (promoted_for_signed_and_unsigned_p): New definition.
> 
> Are you planning to submit some testcases to show its improvement?
> Will it help
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53639
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33349
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44532

Thanks H.J. Lu for the link. I will investigate them and will come up
with test cases if my patches help these.

Kugan
diff mbox

Patch

diff --git a/gcc/calls.c b/gcc/calls.c
index 3be7ca5..6b8d861 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1637,7 +1637,10 @@  precompute_arguments (int num_actuals, struct arg_data *args)
 	      args[i].initial_value
 		= gen_lowpart_SUBREG (mode, args[i].value);
 	      SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
-	      SUBREG_PROMOTED_SET (args[i].initial_value, args[i].unsignedp);
+	      if (promoted_for_signed_and_unsigned_p (args[i].tree_value))
+		SUBREG_PROMOTED_SET (args[i].initial_value, SRP_SIGNED_AND_UNSIGNED);
+	      else
+		SUBREG_PROMOTED_SET (args[i].initial_value, args[i].unsignedp);
 	    }
 	}
     }
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ca491a0..5fcee87 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3452,7 +3452,13 @@  expand_gimple_stmt_1 (gimple stmt)
 					  GET_MODE (target), temp, unsignedp);
 		  }
 
-		convert_move (SUBREG_REG (target), temp, unsignedp);
+		if ((SUBREG_PROMOTED_GET (target) == SRP_SIGNED_AND_UNSIGNED)
+		    && (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
+		  convert_move (SUBREG_REG (target), temp, unsignedp);
 	      }
 	    else if (nontemporal && emit_storent_insn (target, temp))
 	      ;
diff --git a/gcc/expr.c b/gcc/expr.c
index 530a944..224a50f 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -185,6 +185,39 @@  static rtx const_vector_from_tree (tree);
 static tree tree_expr_size (const_tree);
 static HOST_WIDE_INT int_expr_size (tree);
 
+/* Return TRUE if value in SSA is zero and sign extended for wider mode MODE
+   using value range information stored.  Return FALSE otherwise.
+
+   This is used to check if SUBREG is zero and sign extended and to set
+   promoted mode SRP_SIGNED_AND_UNSIGNED to SUBREG.  */
+
+bool
+promoted_for_signed_and_unsigned_p (tree ssa)
+{
+  wide_int min, max;
+  bool ovf;
+
+  if (ssa == NULL_TREE
+      || TREE_CODE (ssa) != SSA_NAME
+      || !INTEGRAL_TYPE_P (TREE_TYPE (ssa)))
+    return false;
+
+  /* Return FALSE if value_range is not recorded for SSA.  */
+  if (get_range_info (ssa, &min, &max, &ovf) != VR_RANGE)
+    return false;
+
+  if (ovf)
+    return false;
+
+  /* Return true (to set SRP_SIGNED_AND_UNSIGNED to SUBREG) if MSB of the
+     smaller mode is not set (i.e.  MSB of ssa is not set).  */
+  if (!wi::neg_p (min, SIGNED) && !wi::neg_p(max, SIGNED))
+    return true;
+  else
+    return false;
+
+}
+
 
 /* This is run to set up which modes can be used
    directly in memory and to initialize the block move optab.  It is run
@@ -9674,7 +9707,10 @@  expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 
 	  temp = gen_lowpart_SUBREG (mode, decl_rtl);
 	  SUBREG_PROMOTED_VAR_P (temp) = 1;
-	  SUBREG_PROMOTED_SET (temp, unsignedp);
+	  if (promoted_for_signed_and_unsigned_p (ssa_name))
+	    SUBREG_PROMOTED_SET (temp, SRP_SIGNED_AND_UNSIGNED);
+	  else
+	    SUBREG_PROMOTED_SET (temp, unsignedp);
 	  return temp;
 	}
 
diff --git a/gcc/expr.h b/gcc/expr.h
index 867852e..f965fe0 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -243,6 +243,7 @@  extern rtx expand_expr_real_1 (tree, rtx, machine_mode,
 			       enum expand_modifier, rtx *, bool);
 extern rtx expand_expr_real_2 (sepops, rtx, machine_mode,
 			       enum expand_modifier);
+extern bool promoted_for_signed_and_unsigned_p (tree);
 
 /* Generate code for computing expression EXP.
    An rtx for the computed value is returned.  The value is never null.