Message ID | 20170310175640.GY22703@tucnak |
---|---|
State | New |
Headers | show |
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
--- 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. */