Slightly improve reassoc optimize_range_tests_var_bound (PR tree-optimization/69615)

Message ID 20180606134857.GK14160@tucnak
State New
Headers show
Series
  • Slightly improve reassoc optimize_range_tests_var_bound (PR tree-optimization/69615)
Related show

Commit Message

Jakub Jelinek June 6, 2018, 1:48 p.m.
Hi!

The following testcase shows another case that can be handled easily.
If rhs2 is defined in a bb dominated by first_bb, we need to be careful
because we can't rely on value range information of it after we optimize the
guarding >= 0 check into 1.  On the testcase, we have there
rhs2 = (int) something_N;
cast where both types are integral with the same precision, so we can in
this case just check if something_N is defined in some bb not dominated by
first_bb, or if it is result of & constant, or zero extension etc.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-06-05  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/69615
	* tree-ssa-reassoc.c (optimize_range_tests_var_bound): If rhs2 is lhs
	of a cast from a same precision integral SSA_NAME in a bb dominated
	by first_bb, retry with rhs2 set to the rhs1 of the cast.  Don't emit
	cast to utype if rhs2 has already a compatible type.

	* gcc.dg/tree-ssa/pr69615.c: New test.


	Jakub

Comments

Richard Biener June 6, 2018, 2:44 p.m. | #1
On Wed, 6 Jun 2018, Jakub Jelinek wrote:

> Hi!

> 

> The following testcase shows another case that can be handled easily.

> If rhs2 is defined in a bb dominated by first_bb, we need to be careful

> because we can't rely on value range information of it after we optimize the

> guarding >= 0 check into 1.  On the testcase, we have there

> rhs2 = (int) something_N;

> cast where both types are integral with the same precision, so we can in

> this case just check if something_N is defined in some bb not dominated by

> first_bb, or if it is result of & constant, or zero extension etc.

> 

> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?


OK.

Thanks,
Richard.

> 2018-06-05  Jakub Jelinek  <jakub@redhat.com>

> 

> 	PR tree-optimization/69615

> 	* tree-ssa-reassoc.c (optimize_range_tests_var_bound): If rhs2 is lhs

> 	of a cast from a same precision integral SSA_NAME in a bb dominated

> 	by first_bb, retry with rhs2 set to the rhs1 of the cast.  Don't emit

> 	cast to utype if rhs2 has already a compatible type.

> 

> 	* gcc.dg/tree-ssa/pr69615.c: New test.

> 

> --- gcc/tree-ssa-reassoc.c.jj	2018-04-27 09:08:57.667850280 +0200

> +++ gcc/tree-ssa-reassoc.c	2018-06-05 17:01:39.028144763 +0200

> @@ -3172,7 +3172,7 @@ optimize_range_tests_var_bound (enum tre

>  	 to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute

>  	 those stmts even for negative k_32 and the value ranges would be no

>  	 longer guaranteed and so the optimization would be invalid.  */

> -      if (opcode == ERROR_MARK)

> +      while (opcode == ERROR_MARK)

>  	{

>  	  gimple *g = SSA_NAME_DEF_STMT (rhs2);

>  	  basic_block bb2 = gimple_bb (g);

> @@ -3182,21 +3182,37 @@ optimize_range_tests_var_bound (enum tre

>  	    {

>  	      /* As an exception, handle a few common cases.  */

>  	      if (gimple_assign_cast_p (g)

> -		  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g)))

> -		  && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)))

> -		  && (TYPE_PRECISION (TREE_TYPE (rhs2))

> -		      > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g)))))

> -		/* Zero-extension is always ok.  */ ;

> +		  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g))))

> +		{

> +		  tree op0 = gimple_assign_rhs1 (g);

> +		  if (TYPE_UNSIGNED (TREE_TYPE (op0))

> +		      && (TYPE_PRECISION (TREE_TYPE (rhs2))

> +			  > TYPE_PRECISION (TREE_TYPE (op0))))

> +		    /* Zero-extension is always ok.  */

> +		    break;

> +		  else if (TYPE_PRECISION (TREE_TYPE (rhs2))

> +			   == TYPE_PRECISION (TREE_TYPE (op0))

> +			   && TREE_CODE (op0) == SSA_NAME)

> +		    {

> +		      /* Cast from signed to unsigned or vice versa.  Retry

> +			 with the op0 as new rhs2.  */

> +		      rhs2 = op0;

> +		      continue;

> +		    }

> +		}

>  	      else if (is_gimple_assign (g)

>  		       && gimple_assign_rhs_code (g) == BIT_AND_EXPR

>  		       && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST

>  		       && !wi::neg_p (wi::to_wide (gimple_assign_rhs2 (g))))

>  		/* Masking with INTEGER_CST with MSB clear is always ok

> -		   too.  */ ;

> -	      else

> -		continue;

> +		   too.  */

> +		break;

> +	      rhs2 = NULL_TREE;

>  	    }

> +	  break;

>  	}

> +      if (rhs2 == NULL_TREE)

> +	continue;

>  

>        wide_int nz = get_nonzero_bits (rhs2);

>        if (wi::neg_p (nz))

> @@ -3253,10 +3269,13 @@ optimize_range_tests_var_bound (enum tre

>        gimple_set_uid (g, uid);

>        rhs1 = gimple_assign_lhs (g);

>        gsi_insert_before (&gsi, g, GSI_SAME_STMT);

> -      g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);

> -      gimple_set_uid (g, uid);

> -      rhs2 = gimple_assign_lhs (g);

> -      gsi_insert_before (&gsi, g, GSI_SAME_STMT);

> +      if (!useless_type_conversion_p (utype, TREE_TYPE (rhs2)))

> +	{

> +	  g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);

> +	  gimple_set_uid (g, uid);

> +	  rhs2 = gimple_assign_lhs (g);

> +	  gsi_insert_before (&gsi, g, GSI_SAME_STMT);

> +	}

>        if (tree_swap_operands_p (rhs1, rhs2))

>  	{

>  	  std::swap (rhs1, rhs2);

> --- gcc/testsuite/gcc.dg/tree-ssa/pr69615.c.jj	2018-06-06 12:55:16.535159073 +0200

> +++ gcc/testsuite/gcc.dg/tree-ssa/pr69615.c	2018-06-06 12:54:53.993133421 +0200

> @@ -0,0 +1,16 @@

> +/* PR tree-optimization/69615 */

> +/* { dg-do compile } */

> +/* { dg-options "-O2 -fdump-tree-optimized" } */

> +/* { dg-final { scan-tree-dump-not " >= 0" "optimized" } } */

> +/* { dg-final { scan-tree-dump-not " < 0" "optimized" } } */

> +

> +extern void foo (void);

> +

> +void

> +bar (int z, unsigned int y)

> +{

> +  long long x = z;

> +  y &= 0xf;

> +  if (x >= 0 && x < (int) y)

> +    foo ();

> +}

> 

> 	Jakub

> 

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

Patch

--- gcc/tree-ssa-reassoc.c.jj	2018-04-27 09:08:57.667850280 +0200
+++ gcc/tree-ssa-reassoc.c	2018-06-05 17:01:39.028144763 +0200
@@ -3172,7 +3172,7 @@  optimize_range_tests_var_bound (enum tre
 	 to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute
 	 those stmts even for negative k_32 and the value ranges would be no
 	 longer guaranteed and so the optimization would be invalid.  */
-      if (opcode == ERROR_MARK)
+      while (opcode == ERROR_MARK)
 	{
 	  gimple *g = SSA_NAME_DEF_STMT (rhs2);
 	  basic_block bb2 = gimple_bb (g);
@@ -3182,21 +3182,37 @@  optimize_range_tests_var_bound (enum tre
 	    {
 	      /* As an exception, handle a few common cases.  */
 	      if (gimple_assign_cast_p (g)
-		  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g)))
-		  && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)))
-		  && (TYPE_PRECISION (TREE_TYPE (rhs2))
-		      > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g)))))
-		/* Zero-extension is always ok.  */ ;
+		  && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g))))
+		{
+		  tree op0 = gimple_assign_rhs1 (g);
+		  if (TYPE_UNSIGNED (TREE_TYPE (op0))
+		      && (TYPE_PRECISION (TREE_TYPE (rhs2))
+			  > TYPE_PRECISION (TREE_TYPE (op0))))
+		    /* Zero-extension is always ok.  */
+		    break;
+		  else if (TYPE_PRECISION (TREE_TYPE (rhs2))
+			   == TYPE_PRECISION (TREE_TYPE (op0))
+			   && TREE_CODE (op0) == SSA_NAME)
+		    {
+		      /* Cast from signed to unsigned or vice versa.  Retry
+			 with the op0 as new rhs2.  */
+		      rhs2 = op0;
+		      continue;
+		    }
+		}
 	      else if (is_gimple_assign (g)
 		       && gimple_assign_rhs_code (g) == BIT_AND_EXPR
 		       && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST
 		       && !wi::neg_p (wi::to_wide (gimple_assign_rhs2 (g))))
 		/* Masking with INTEGER_CST with MSB clear is always ok
-		   too.  */ ;
-	      else
-		continue;
+		   too.  */
+		break;
+	      rhs2 = NULL_TREE;
 	    }
+	  break;
 	}
+      if (rhs2 == NULL_TREE)
+	continue;
 
       wide_int nz = get_nonzero_bits (rhs2);
       if (wi::neg_p (nz))
@@ -3253,10 +3269,13 @@  optimize_range_tests_var_bound (enum tre
       gimple_set_uid (g, uid);
       rhs1 = gimple_assign_lhs (g);
       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);
-      gimple_set_uid (g, uid);
-      rhs2 = gimple_assign_lhs (g);
-      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+      if (!useless_type_conversion_p (utype, TREE_TYPE (rhs2)))
+	{
+	  g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);
+	  gimple_set_uid (g, uid);
+	  rhs2 = gimple_assign_lhs (g);
+	  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+	}
       if (tree_swap_operands_p (rhs1, rhs2))
 	{
 	  std::swap (rhs1, rhs2);
--- gcc/testsuite/gcc.dg/tree-ssa/pr69615.c.jj	2018-06-06 12:55:16.535159073 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr69615.c	2018-06-06 12:54:53.993133421 +0200
@@ -0,0 +1,16 @@ 
+/* PR tree-optimization/69615 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " >= 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < 0" "optimized" } } */
+
+extern void foo (void);
+
+void
+bar (int z, unsigned int y)
+{
+  long long x = z;
+  y &= 0xf;
+  if (x >= 0 && x < (int) y)
+    foo ();
+}