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?

2017-03-10  Jakub Jelinek  <ja...@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

Reply via email to