diff mbox

Improve VRP for IMAGPART_EXPR of ATOMIC_COMPARE_EXCHANGE ifn (PR tree-optimization/79981)

Message ID 20170310175640.GY22703@tucnak
State New
Headers show

Commit Message

Jakub Jelinek March 10, 2017, 5:56 p.m. UTC
Hi!

The following patch teaches VRP that IMAGPART_EXPR of
ATOMIC_COMPARE_EXCHANGE ifn call is always 0 or 1.  We cast it to bool
afterwards, but this hint allows VRP to:

	Jakub

Comments

Richard Biener March 10, 2017, 7:26 p.m. UTC | #1
On March 10, 2017 6:56:40 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>The following patch teaches VRP that IMAGPART_EXPR of
>ATOMIC_COMPARE_EXCHANGE ifn call is always 0 or 1.  We cast it to bool
>afterwards, but this hint allows VRP to:
>--- pr79981.c.103t.vrp1_	2017-03-10 15:39:29.000000000 +0100
>+++ pr79981.c.103t.vrp1	2017-03-10 15:48:15.051608067 +0100
>@@ -17,7 +17,7 @@ Value ranges after VRP:
> _1: [0, +INF]
> .MEM_2: VARYING
> _8: VARYING
>-_9: [0, +INF]
>+_9: [0, 1]
> 
> 
> csi (int * lock)
>@@ -32,11 +32,11 @@ csi (int * lock)
>   # USE = nonlocal null 
>   # CLB = nonlocal null 
>   _8 = ATOMIC_COMPARE_EXCHANGE (lock_4(D), 0, 1, 260, 2, 0);
>-  # RANGE [0, 4294967295]
>+  # RANGE [0, 1] NONZERO 1
>   _9 = IMAGPART_EXPR <_8>;
>   # RANGE [0, 1]
>   _1 = (_Bool) _9;
>-  if (_1 != 0)
>+  if (_9 != 0)
>     goto <bb 3>; [99.96%]
>   else
>     goto <bb 4>; [0.04%]
>which should be beneficial e.g. for s390x code generation.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-03-10  Jakub Jelinek  <jakub@redhat.com>
>
>	PR tree-optimization/79981
>	* tree-vrp.c (extract_range_basic): Handle IMAGPART_EXPR of
>	ATOMIC_COMPARE_EXCHANGE ifn result.
>	(stmt_interesting_for_vrp, vrp_visit_stmt): Handle
>	IFN_ATOMIC_COMPARE_EXCHANGE.
>
>--- gcc/tree-vrp.c.jj	2017-02-22 18:15:48.000000000 +0100
>+++ gcc/tree-vrp.c	2017-03-10 15:45:30.574778201 +0100
>@@ -4107,7 +4107,7 @@ extract_range_basic (value_range *vr, gi
>     }
>   /* Handle extraction of the two results (result of arithmetics and
>     a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
>-     internal function.  */
>+     internal function.  Similarly from ATOMIC_COMPARE_EXCHANGE.  */
>   else if (is_gimple_assign (stmt)
> 	   && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
> 	       || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
>@@ -4132,6 +4132,16 @@ extract_range_basic (value_range *vr, gi
> 		case IFN_MUL_OVERFLOW:
> 		  subcode = MULT_EXPR;
> 		  break;
>+		case IFN_ATOMIC_COMPARE_EXCHANGE:
>+		  if (code == IMAGPART_EXPR)
>+		    {
>+		      /* This is the boolean return value whether compare and
>+			 exchange changed anything or not.  */
>+		      set_value_range (vr, VR_RANGE, build_int_cst (type, 0),
>+				       build_int_cst (type, 1), NULL);
>+		      return;
>+		    }
>+		  break;
> 		default:
> 		  break;
> 		}
>@@ -7283,6 +7293,7 @@ stmt_interesting_for_vrp (gimple *stmt)
> 	  case IFN_ADD_OVERFLOW:
> 	  case IFN_SUB_OVERFLOW:
> 	  case IFN_MUL_OVERFLOW:
>+	  case IFN_ATOMIC_COMPARE_EXCHANGE:
> 	    /* These internal calls return _Complex integer type,
> 	       but are interesting to VRP nevertheless.  */
> 	    if (lhs && TREE_CODE (lhs) == SSA_NAME)
>@@ -8308,6 +8319,7 @@ vrp_visit_stmt (gimple *stmt, edge *take
>       case IFN_ADD_OVERFLOW:
>       case IFN_SUB_OVERFLOW:
>       case IFN_MUL_OVERFLOW:
>+      case IFN_ATOMIC_COMPARE_EXCHANGE:
> 	/* These internal calls return _Complex integer type,
> 	   which VRP does not track, but the immediate uses
> 	   thereof might be interesting.  */
>
>	Jakub
diff mbox

Patch

--- pr79981.c.103t.vrp1_	2017-03-10 15:39:29.000000000 +0100
+++ pr79981.c.103t.vrp1	2017-03-10 15:48:15.051608067 +0100
@@ -17,7 +17,7 @@  Value ranges after VRP:
 _1: [0, +INF]
 .MEM_2: VARYING
 _8: VARYING
-_9: [0, +INF]
+_9: [0, 1]
 
 
 csi (int * lock)
@@ -32,11 +32,11 @@  csi (int * lock)
   # USE = nonlocal null 
   # CLB = nonlocal null 
   _8 = ATOMIC_COMPARE_EXCHANGE (lock_4(D), 0, 1, 260, 2, 0);
-  # RANGE [0, 4294967295]
+  # RANGE [0, 1] NONZERO 1
   _9 = IMAGPART_EXPR <_8>;
   # RANGE [0, 1]
   _1 = (_Bool) _9;
-  if (_1 != 0)
+  if (_9 != 0)
     goto <bb 3>; [99.96%]
   else
     goto <bb 4>; [0.04%]
which should be beneficial e.g. for s390x code generation.

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

2017-03-10  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/79981
	* tree-vrp.c (extract_range_basic): Handle IMAGPART_EXPR of
	ATOMIC_COMPARE_EXCHANGE ifn result.
	(stmt_interesting_for_vrp, vrp_visit_stmt): Handle
	IFN_ATOMIC_COMPARE_EXCHANGE.

--- gcc/tree-vrp.c.jj	2017-02-22 18:15:48.000000000 +0100
+++ gcc/tree-vrp.c	2017-03-10 15:45:30.574778201 +0100
@@ -4107,7 +4107,7 @@  extract_range_basic (value_range *vr, gi
     }
   /* Handle extraction of the two results (result of arithmetics and
      a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
-     internal function.  */
+     internal function.  Similarly from ATOMIC_COMPARE_EXCHANGE.  */
   else if (is_gimple_assign (stmt)
 	   && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
 	       || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
@@ -4132,6 +4132,16 @@  extract_range_basic (value_range *vr, gi
 		case IFN_MUL_OVERFLOW:
 		  subcode = MULT_EXPR;
 		  break;
+		case IFN_ATOMIC_COMPARE_EXCHANGE:
+		  if (code == IMAGPART_EXPR)
+		    {
+		      /* This is the boolean return value whether compare and
+			 exchange changed anything or not.  */
+		      set_value_range (vr, VR_RANGE, build_int_cst (type, 0),
+				       build_int_cst (type, 1), NULL);
+		      return;
+		    }
+		  break;
 		default:
 		  break;
 		}
@@ -7283,6 +7293,7 @@  stmt_interesting_for_vrp (gimple *stmt)
 	  case IFN_ADD_OVERFLOW:
 	  case IFN_SUB_OVERFLOW:
 	  case IFN_MUL_OVERFLOW:
+	  case IFN_ATOMIC_COMPARE_EXCHANGE:
 	    /* These internal calls return _Complex integer type,
 	       but are interesting to VRP nevertheless.  */
 	    if (lhs && TREE_CODE (lhs) == SSA_NAME)
@@ -8308,6 +8319,7 @@  vrp_visit_stmt (gimple *stmt, edge *take
       case IFN_ADD_OVERFLOW:
       case IFN_SUB_OVERFLOW:
       case IFN_MUL_OVERFLOW:
+      case IFN_ATOMIC_COMPARE_EXCHANGE:
 	/* These internal calls return _Complex integer type,
 	   which VRP does not track, but the immediate uses
 	   thereof might be interesting.  */