[Bug tree-optimization/69013] [5/6 Regression] gfortran-5.3.0 ICE in prune_uninit_phi_opnds_in_unrealizable_paths, at tree-ssa-uninit.c:1121

2016-01-08 Thread davidxl at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69013

davidxl at google dot com changed:

   What|Removed |Added

 CC||davidxl at google dot com

--- Comment #5 from davidxl at google dot com ---
The assertion is indeed too strict. See

static unsigned
compute_uninit_opnds_pos (gphi *phi)
{
  size_t i, n;
  unsigned uninit_opnds = 0;

  n = gimple_phi_num_args (phi);
  /* Bail out for phi with too many args.  */
  if (n > 32)
return 0;
 ...
}

it is possible that empty bitset is returned -- so the fix looks ok.

[Bug tree-optimization/59303] [4.9 Regression] uninit-pred-8_b.c and uninit-pred-9_b.c fail after better optimizations

2013-12-21 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59303

--- Comment #8 from davidxl at google dot com ---
Created attachment 31495
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=31495action=edit
Patch file : cleanup + more predicate simplification rules


[Bug tree-optimization/59303] [4.9 Regression] uninit-pred-8_b.c and uninit-pred-9_b.c fail after better optimizations

2013-12-21 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59303

--- Comment #10 from davidxl at google dot com ---
My patch does this.
1) it first does aggressive simplification iteratively (more rules can be added
later). 
2) it then does normalization by building up larger predicate trees by
following ud chain and bitwise or/and operations. It handles simple PHIs
including also degenerated phis.

The new dump reports:

in foo,

predicate for def:

m_7(D)  100
(.OR.)
n_5(D) = 9
(.OR.)
l_12(D) != 0
(.OR.)
r_10(D) = 19

use1:

m_7(D)  100
(.OR.)
n_5(D) = 9
(.OR.)
r_10(D) = 9

use2:

m_7(D)  100
(.OR.)
n_5(D) = 9
(.OR.)
r_10(D) = 19


For foo2, the predicates are properly built, but the patch has a bug in
predicate set inclusion testing leading to a false negative.

David

(In reply to Jakub Jelinek from comment #9)
 Created attachment 31496 [details]
 cleanups
 
 I had also a brief look at this recently, but haven't made progress beyond
 attached formatting/cleanup patch so far (plus only dumping details with
 *-details, otherwise the dumps are pretty much inconsistent).
 My conclusion has also been that to fix this up the predicates would need to
 be normalized before comparison, and simplified, at least if the initial
 subset check fails.  On uninit-pred-8_b.c there has been additional
 complication because PRE decides to change the IL and we end up with:
   bb 3:
   pretmp_24 = r_10(D) = 19;
   goto bb 5;
 
   bb 4:
   _11 = r_10(D) = 19;
   _13 = l_12(D) != 0;
   _14 = _11 | _13;
   if (_14 != 0)
 goto bb 14;
   else
 goto bb 15;
 
   bb 14:
   goto bb 3;
   
   bb 15:
 
   bb 5:
   # v_1 = PHI v_15(D)(15), r_10(D)(3)
   # prephitmp_30 = PHI 0(15), pretmp_24(3)
   if (m_7(D) != 0)
 goto bb 6;
   else
 goto bb 7;
 
   bb 6:
   g.0_17 = g;
   g.1_18 = g.0_17 + 1;
   g = g.1_18;
   goto bb 8;
   
   bb 7:
   bar ();
 
   bb 8:
   _3 = prephitmp_30 | _9;
   if (_3 != 0)
 so the prephitmp_30 would need to be canonicalized into _14 != 0  r_10(D)
 = 19 aka (r_10(D) = 19 || l_12(D) != 0)  r_10(D) = 19 and from there to
 r_10(D) = 19.


[Bug tree-optimization/59303] [4.9 Regression] uninit-pred-8_b.c and uninit-pred-9_b.c fail after better optimizations

2013-12-21 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59303

--- Comment #11 from davidxl at google dot com ---
The false negative bug introduced in the patch is fixed. Will submit the patch
for review soon.

(In reply to davidxl from comment #10)
 My patch does this.
 1) it first does aggressive simplification iteratively (more rules can be
 added later). 
 2) it then does normalization by building up larger predicate trees by
 following ud chain and bitwise or/and operations. It handles simple PHIs
 including also degenerated phis.
 
 The new dump reports:
 
 in foo,
 
 predicate for def:
 
 m_7(D)  100
 (.OR.)
 n_5(D) = 9
 (.OR.)
 l_12(D) != 0
 (.OR.)
 r_10(D) = 19
 
 use1:
 
 m_7(D)  100
 (.OR.)
 n_5(D) = 9
 (.OR.)
 r_10(D) = 9
 
 use2:
 
 m_7(D)  100
 (.OR.)
 n_5(D) = 9
 (.OR.)
 r_10(D) = 19
 
 
 For foo2, the predicates are properly built, but the patch has a bug in
 predicate set inclusion testing leading to a false negative.
 
 David
 
 (In reply to Jakub Jelinek from comment #9)
  Created attachment 31496 [details]
  cleanups
  
  I had also a brief look at this recently, but haven't made progress beyond
  attached formatting/cleanup patch so far (plus only dumping details with
  *-details, otherwise the dumps are pretty much inconsistent).
  My conclusion has also been that to fix this up the predicates would need to
  be normalized before comparison, and simplified, at least if the initial
  subset check fails.  On uninit-pred-8_b.c there has been additional
  complication because PRE decides to change the IL and we end up with:
bb 3:
pretmp_24 = r_10(D) = 19;
goto bb 5;
  
bb 4:
_11 = r_10(D) = 19;
_13 = l_12(D) != 0;
_14 = _11 | _13;
if (_14 != 0)
  goto bb 14;
else
  goto bb 15;
  
bb 14:
goto bb 3;

bb 15:
  
bb 5:
# v_1 = PHI v_15(D)(15), r_10(D)(3)
# prephitmp_30 = PHI 0(15), pretmp_24(3)
if (m_7(D) != 0)
  goto bb 6;
else
  goto bb 7;
  
bb 6:
g.0_17 = g;
g.1_18 = g.0_17 + 1;
g = g.1_18;
goto bb 8;

bb 7:
bar ();
  
bb 8:
_3 = prephitmp_30 | _9;
if (_3 != 0)
  so the prephitmp_30 would need to be canonicalized into _14 != 0  r_10(D)
  = 19 aka (r_10(D) = 19 || l_12(D) != 0)  r_10(D) = 19 and from there to
  r_10(D) = 19.


[Bug tree-optimization/59303] [4.9 Regression] uninit-pred-8_b.c and uninit-pred-9_b.c fail after better optimizations

2013-12-19 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59303

davidxl at google dot com changed:

   What|Removed |Added

 CC||davidxl at google dot com

--- Comment #7 from davidxl at google dot com ---
Testing a fix that addresses the problem. With the fix, the dump shows:

Use in stmt: blah (v_1);
is guarded by :
m_6(D)  100
(.OR.)
n_4(D) = 9
(.OR.)
r_9(D) = 19

Operand defs of phi: v_1 = PHI v_14(D)(13), r_9(D)(3)
is guarded by :
m_6(D)  100
(.OR.)
n_4(D) = 9
(.OR.)
l_11(D) != 0
(.OR.)
r_9(D) = 19

which is correct.


[Bug c++/58377] spurious may be used uninitialized warning with -Og

2013-09-10 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377

davidxl at google dot com changed:

   What|Removed |Added

 CC||davidxl at google dot com

--- Comment #6 from davidxl at google dot com ---
There are some spurious PHIs (for out) with -g.

Bad dot file (-g):

digraph t.cc.153t.uninit2 {
overlap=false;
subgraph int my_pop() {
color=black;
label=int my_pop();
fn_0_basic_block_1
[shape=Mdiamond,style=filled,fillcolor=white,label=EXIT];

fn_0_basic_block_2 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:880 |\bb\ 2\:\l\
goto\ \bb\ 7\;\l\
}];

fn_0_basic_block_7 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:1 |\bb\ 7\:\l\
|#\ out_2\ =\ PHI\ \out_8(D)(2),\ out_1(6)\\l\
|pop_first_bucket.2_10\ =\ pop_first_bucket;\l\
|if\ (pop_first_bucket.2_10\ !=\ 0)\l\
\ \ goto\ \bb\ 3\;\l\
else\l\
\ \ goto\ \bb\ 8\;\l\
}];

fn_0_basic_block_3 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:9550 |\bb\ 3\:\l\
|if\ (pop_first_bucket.2_10\ !=\ 0)\l\
\ \ goto\ \bb\ 4\;\l\
else\l\
\ \ goto\ \bb\ 6\;\l\
}];

fn_0_basic_block_4 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:2769 |\bb\ 4\:\l\
|out_12\ =\ pop\ ();\l\
|if\ (out_12\ !=\ 0)\l\
\ \ goto\ \bb\ 6\;\l\
else\l\
\ \ goto\ \bb\ 5\;\l\
}];

fn_0_basic_block_5 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:2520 |\bb\ 5\:\l\
}];

fn_0_basic_block_6 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:9550 |\bb\ 6\:\l\
|#\ out_1\ =\ PHI\ \out_12(4),\ out_12(5),\ out_2(3)\\l\
|#\ iftmp.1_3\ =\ PHI\ \1(4),\ 0(5),\ 0(3)\\l\
|if\ (iftmp.1_3\ !=\ 0)\l\
\ \ goto\ \bb\ 8\;\l\
else\l\
\ \ goto\ \bb\ 7\;\l\
}];

fn_0_basic_block_8 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:880 |\bb\ 8\:\l\
|#\ _4\ =\ PHI\ \out_1(6),\ 0(7)\\l\
|return\ _4;\l\
}];

fn_0_basic_block_0
[shape=Mdiamond,style=filled,fillcolor=white,label=ENTRY];

fn_0_basic_block_0:s - fn_0_basic_block_2:n
[style=solid,bold,color=blue,weight=100,constraint=true, label=[100%]];
fn_0_basic_block_2:s - fn_0_basic_block_7:n
[style=solid,bold,color=blue,weight=100,constraint=true, label=[100%]];
fn_0_basic_block_3:s - fn_0_basic_block_4:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[29%]];
fn_0_basic_block_3:s - fn_0_basic_block_6:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[71%]];
fn_0_basic_block_4:s - fn_0_basic_block_6:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[9%]];
fn_0_basic_block_4:s - fn_0_basic_block_5:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[91%]];
fn_0_basic_block_5:s - fn_0_basic_block_6:n
[style=solid,bold,color=blue,weight=100,constraint=true, label=[100%]];
fn_0_basic_block_6:s - fn_0_basic_block_8:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[4%]];
fn_0_basic_block_6:s - fn_0_basic_block_7:n
[style=dotted,bold,color=blue,weight=10,constraint=false, label=[95%]];
fn_0_basic_block_7:s - fn_0_basic_block_3:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[95%]];
fn_0_basic_block_7:s - fn_0_basic_block_8:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[4%]];
fn_0_basic_block_8:s - fn_0_basic_block_1:n
[style=solid,bold,color=black,weight=10,constraint=true, label=[100%]];
fn_0_basic_block_0:s - fn_0_basic_block_1:n
[style=invis,constraint=true];
}
}


GCC reports unguarded use of out at return statement. return value is defined
by

 _4 = PHI (out_1(6), 0(7))

where

out_1 = PHI (out_12 (4), out_12 (5), out_2 (3))

where

out_2 = PHI (out_8(D)(2), out_1 (6))

This phi introduces uninitialized variable use.


To compare, the good dot file is :

digraph t.cc.133t.uninit1 {
overlap=false;
subgraph int my_pop() {
color=black;
label=int my_pop();
subgraph cluster_0_1 {
style=filled;
color=darkgreen;
fillcolor=grey88;
label=loop 1;
labeljust=l;
penwidth=2;
fn_0_basic_block_5 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:1 |\bb\ 5\:\l\
|pop_first_bucket.2_10\ =\ pop_first_bucket;\l\
|if\ (pop_first_bucket.2_10\ !=\ 0)\l\
\ \ goto\ \bb\ 3\;\l\
else\l\
\ \ goto\ \bb\ 6\;\l\
}];

fn_0_basic_block_3 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:2769 |\bb\ 3\:\l\
|out_12\ =\ pop\ ();\l\
|if\ (out_12\ !=\ 0)\l\
\ \ goto\ \bb\ 6\;\l\
else\l\
\ \ goto\ \bb\ 4\;\l\
}];

fn_0_basic_block_4 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:2520 |\bb\ 4\:\l\
}];

}
fn_0_basic_block_0
[shape=Mdiamond,style=filled,fillcolor=white,label=ENTRY];

fn_0_basic_block_1
[shape=Mdiamond,style=filled,fillcolor=white,label=EXIT];

fn_0_basic_block_2 [shape=record,style=filled,fillcolor=lightgrey,label={
FREQ:880 |\bb\ 2\:\l\
goto\ \bb\ 5\;\l\
}];

fn_0_basic_block_6

[Bug c++/58377] spurious may be used uninitialized warning with -Og

2013-09-10 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377

--- Comment #8 from davidxl at google dot com ---
(In reply to Neil Vachharajani from comment #7)
 It seems like the whole problem is that the loop early exit goes through
 bb_6 which is the same path the back-edge goes through.

There is also one thing weird about the trunk GCC's IR


Why is constant 0 propagated into the PHI node?

_4 = PHI out_13(7), 0(9)

From the CFG, it should be like

_4 = PHI out_13(7), out_2(9)   ?


[Bug c++/58377] spurious may be used uninitialized warning with -Og

2013-09-10 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377

--- Comment #9 from davidxl at google dot com ---
(In reply to Richard Biener from comment #5)
 Confirmed with the C++ FE, works with the C FE.  Does not warn on trunk (for
 no good reason I think, the reason seems to be presence of loop structure
 and thus some extra BBs).
 
 Difference:
 
 trunk:
 
 [WORKLIST]: add to initial list: out_2 = PHI out_8(D)(2), out_1(8)
 [CHECK]: examining phi: out_2 = PHI out_8(D)(2), out_1(8)
 
 Use in stmt out_1 = PHI out_12(4), out_12(5), out_2(3)
 is guarded by :
 if (pop_first_bucket.2_10 != 0)
 
 [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 
 [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 Operand defs of phi out_2 = PHI out_8(D)(2), out_1(8)
 is guarded by :
 if (out_12 != 0)
 [CHECK]: Found unguarded use: out_1 = PHI out_12(4), out_12(5), out_2(3)
 [WORKLIST]: Update worklist with phi: out_1 = PHI out_12(4), out_12(5),
 out_2(3)
 [CHECK]: examining phi: out_1 = PHI out_12(4), out_12(5), out_2(3)
 
 Use in stmt out_2 = PHI out_8(D)(2), out_1(8)
 is guarded by :
  (.NOT.) if (iftmp.1_3 != 0)
 
 [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 
 [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 Operand defs of phi out_1 = PHI out_12(4), out_12(5), out_2(3)
 is guarded by :
 if (pop_first_bucket.2_10 != 0)
 (.AND.)
 if (out_12 != 0)
 (.OR.)
 if (pop_first_bucket.2_10 != 0)
 (.AND.)
  (.NOT.) if (out_12 != 0)
 
 Normalized to
 Operand defs of phi out_1 = PHI out_12(4), out_12(5), out_2(3)
 is guarded by :
 if (pop_first_bucket.2_10 != 0)
 ...
 
 vs. 4.8 branch:
 
 [WORKLIST]: add to initial list: out_2 = PHI out_8(D)(2), out_1(6)
 [CHECK]: examining phi: out_2 = PHI out_8(D)(2), out_1(6)
 
 Use in stmt out_1 = PHI out_12(4), out_12(5), out_2(3)
 is guarded by :
 if (pop_first_bucket.2_10 != 0)
 
 [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 
 [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
 Operand defs of phi out_2 = PHI out_8(D)(2), out_1(6)
 is guarded by :
 if (out_12 != 0)
 [CHECK]: Found unguarded use: out_1 = PHI out_12(4), out_12(5), out_2(3)
 [WORKLIST]: Update worklist with phi: out_1 = PHI out_12(4), out_12(5),
 out_2(3)
 [CHECK]: examining phi: out_1 = PHI out_12(4), out_12(5), out_2(3)
 [CHECK]: Found unguarded use: out_2 = PHI out_8(D)(2), out_1(6)
 [CHECK]: Found unguarded use: _4 = PHI out_1(6), 0(7)
 [WORKLIST]: Update worklist with phi: _4 = PHI out_1(6), 0(7)
 [CHECK]: examining phi: _4 = PHI out_1(6), 0(7)
 [CHECK]: Found unguarded use: return _4;
 
 The IL difference is that we have
 
   bb 6:
   # out_1 = PHI out_12(4), out_12(5), out_2(3)
   # iftmp.1_3 = PHI 1(4), 0(5), 0(3)
   if (iftmp.1_3 != 0)
 goto bb 7;
   else
 goto bb 8;
 
   bb 7:
   out_13 = out_1;
   goto bb 10;
 ...
   bb 10:
   # _4 = PHI out_13(7), 0(9)
   return _4;
 
 which doesn't warn vs.
 
   bb 6:
   # out_1 = PHI out_12(4), out_12(5), out_2(3)
   # iftmp.1_3 = PHI 1(4), 0(5), 0(3)
   if (iftmp.1_3 != 0)
 goto bb 8;
   else
 goto bb 7;
 ...
   bb 8:
   # _4 = PHI out_1(6), 0(7)
   return _4;
 
 which does.  The issue seems to be that the analysis doesn't consider
 the PHI uses in
 
   if (iftmp.1_3 != 0)
 goto bb 8;
   else
 goto bb 7;
 
   bb 7:
   # out_2 = PHI out_8(D)(2), out_1(6)
 
 guarded by anything (the out_1 use is guarded by iftmp.1_3 == 0).
 
 David - the code does
 
   if (gimple_code (use_stmt) == GIMPLE_PHI)
 use_bb = gimple_phi_arg_edge (use_stmt,
   PHI_ARG_INDEX_FROM_USE (use_p))-src;
   else
 use_bb = gimple_bb (use_stmt);
 
   if (is_use_properly_guarded (use_stmt,
use_bb,
 ...
 
 so it chooses the source block (as approximation?).
 
 Splitting all edges results in us no longer warning here and:
 
 Use in stmt out_2 = PHI out_8(D)(15), out_1(16)
 is guarded by :
  (.NOT.) if (iftmp.1_3 != 0)
 
 Can you see to fix that please?  Thanks.


Your analysis is correct -- the use is indeed guarded. I forgot why I chose to
use the phi arg's source BB. Will take a look.

David


[Bug c++/58377] spurious may be used uninitialized warning with -Og

2013-09-10 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377

--- Comment #10 from davidxl at google dot com ---

When an incoming edge to a phi is a critical edge, the 'use BB' for the phi arg
should be in the split BB of the edge. Pushing the use into either the Source
BB  or the dest BB will result in extending the 'use' falsely in more BBs.  In
this case, simply use the PHI's BB won't solve the problem, as there is an
incoming path introduced not guarded by if (iftmp.1_3 != 0)

I don't see a good way to fix it unless splitting the edge.

David


(In reply to davidxl from comment #9)
 (In reply to Richard Biener from comment #5)
  Confirmed with the C++ FE, works with the C FE.  Does not warn on trunk (for
  no good reason I think, the reason seems to be presence of loop structure
  and thus some extra BBs).
  
  Difference:
  
  trunk:
  
  [WORKLIST]: add to initial list: out_2 = PHI out_8(D)(2), out_1(8)
  [CHECK]: examining phi: out_2 = PHI out_8(D)(2), out_1(8)
  
  Use in stmt out_1 = PHI out_12(4), out_12(5), out_2(3)
  is guarded by :
  if (pop_first_bucket.2_10 != 0)
  
  [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  
  [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  Operand defs of phi out_2 = PHI out_8(D)(2), out_1(8)
  is guarded by :
  if (out_12 != 0)
  [CHECK]: Found unguarded use: out_1 = PHI out_12(4), out_12(5), out_2(3)
  [WORKLIST]: Update worklist with phi: out_1 = PHI out_12(4), out_12(5),
  out_2(3)
  [CHECK]: examining phi: out_1 = PHI out_12(4), out_12(5), out_2(3)
  
  Use in stmt out_2 = PHI out_8(D)(2), out_1(8)
  is guarded by :
   (.NOT.) if (iftmp.1_3 != 0)
  
  [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  
  [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  Operand defs of phi out_1 = PHI out_12(4), out_12(5), out_2(3)
  is guarded by :
  if (pop_first_bucket.2_10 != 0)
  (.AND.)
  if (out_12 != 0)
  (.OR.)
  if (pop_first_bucket.2_10 != 0)
  (.AND.)
   (.NOT.) if (out_12 != 0)
  
  Normalized to
  Operand defs of phi out_1 = PHI out_12(4), out_12(5), out_2(3)
  is guarded by :
  if (pop_first_bucket.2_10 != 0)
  ...
  
  vs. 4.8 branch:
  
  [WORKLIST]: add to initial list: out_2 = PHI out_8(D)(2), out_1(6)
  [CHECK]: examining phi: out_2 = PHI out_8(D)(2), out_1(6)
  
  Use in stmt out_1 = PHI out_12(4), out_12(5), out_2(3)
  is guarded by :
  if (pop_first_bucket.2_10 != 0)
  
  [CHECK] Found def edge 0 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  
  [CHECK] Found def edge 1 in out_1 = PHI out_12(4), out_12(5), out_2(3)
  Operand defs of phi out_2 = PHI out_8(D)(2), out_1(6)
  is guarded by :
  if (out_12 != 0)
  [CHECK]: Found unguarded use: out_1 = PHI out_12(4), out_12(5), out_2(3)
  [WORKLIST]: Update worklist with phi: out_1 = PHI out_12(4), out_12(5),
  out_2(3)
  [CHECK]: examining phi: out_1 = PHI out_12(4), out_12(5), out_2(3)
  [CHECK]: Found unguarded use: out_2 = PHI out_8(D)(2), out_1(6)
  [CHECK]: Found unguarded use: _4 = PHI out_1(6), 0(7)
  [WORKLIST]: Update worklist with phi: _4 = PHI out_1(6), 0(7)
  [CHECK]: examining phi: _4 = PHI out_1(6), 0(7)
  [CHECK]: Found unguarded use: return _4;
  
  The IL difference is that we have
  
bb 6:
# out_1 = PHI out_12(4), out_12(5), out_2(3)
# iftmp.1_3 = PHI 1(4), 0(5), 0(3)
if (iftmp.1_3 != 0)
  goto bb 7;
else
  goto bb 8;
  
bb 7:
out_13 = out_1;
goto bb 10;
  ...
bb 10:
# _4 = PHI out_13(7), 0(9)
return _4;
  
  which doesn't warn vs.
  
bb 6:
# out_1 = PHI out_12(4), out_12(5), out_2(3)
# iftmp.1_3 = PHI 1(4), 0(5), 0(3)
if (iftmp.1_3 != 0)
  goto bb 8;
else
  goto bb 7;
  ...
bb 8:
# _4 = PHI out_1(6), 0(7)
return _4;
  
  which does.  The issue seems to be that the analysis doesn't consider
  the PHI uses in
  
if (iftmp.1_3 != 0)
  goto bb 8;
else
  goto bb 7;
  
bb 7:
# out_2 = PHI out_8(D)(2), out_1(6)
  
  guarded by anything (the out_1 use is guarded by iftmp.1_3 == 0).
  
  David - the code does
  
if (gimple_code (use_stmt) == GIMPLE_PHI)
  use_bb = gimple_phi_arg_edge (use_stmt,
PHI_ARG_INDEX_FROM_USE (use_p))-src;
else
  use_bb = gimple_bb (use_stmt);
  
if (is_use_properly_guarded (use_stmt,
 use_bb,
  ...
  
  so it chooses the source block (as approximation?).
  
  Splitting all edges results in us no longer warning here and:
  
  Use in stmt out_2 = PHI out_8(D)(15), out_1(16)
  is guarded by :
   (.NOT.) if (iftmp.1_3 != 0)
  
  Can you see to fix that please?  Thanks.
 
 
 Your analysis is correct -- the use is indeed guarded. I forgot why I chose
 to use the phi arg's source BB. Will take a look.
 
 David


[Bug c++/57375] gnu multiversioning selects different version depending on link order

2013-05-23 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57375

--- Comment #3 from davidxl at google dot com ---
(In reply to Sriraman Tallam from comment #2)
 IMO, This is working as expected.
 
 You define corei7 only in mv12-aux1.cc, so the compilation of mv12.C and
 mv12-aux.cc do not see the corei7 version.  The version resolver function
 that is generated is a comdat function, and there are 2 copies generated for
 the 2 source files with a call to foo, mv12.C and mv12-aux1.cc. However, one
 of the copies is different, that generated when compiling mv12-aux1.cc
 because it has the extra corei7  version.  So, depending on the link order
 whichever comdat copy gets kept either calls the corei7 version or not.
 Usually, the linker keeps the first comdat copy seen so if you put
 mv12-aux1.cc ahead of mv12.C, the corei7 version will be called and the
 reverse will not call it.
 
 The fix is in the source. Either make every source file see the corei7
 version or hide it from all. 
 
 The linker can be made to complain that the comdats differ if it could be
 taught about version resolvers. This may be more involved.


There is no need to conditionally declare/define corei7 version in one file
only -- the additional time cost is very small.

David


[Bug c++/57378] gnu multiversioning gives assembler error: foo.resolver is already defined

2013-05-23 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57378

--- Comment #3 from davidxl at google dot com ---

Can the resolver node be updated? or a new dispatcher/resolver is created?

The user code looks fine to me, which exposes the implementation limitation.

David

(In reply to Sriraman Tallam from comment #2)
 First, what is happening here is the first call to foo is only seeing 2
 versions and the second call to foo is seeing the 3rd corei7 version. Was
 this intentional?  
 
 When the dispatcher/resovler decl is created, the cgraph nodes of all
 versions are mapped to this decl. However, the new version decl (corei7
 version) is created later, after the first call, and hence it is not mapped
 to the dispatcher function decl that was previously generated. Hence the
 second call re-generates it.
 
 There are a couple of issues here. Should the first call to foo () even get
 access to the corei7 version which is not visible? If the corei7 version
 should not be visible to the first call I must create 2 resolvers, one for
 the first call and the other for the second call.  This gets complicated and
 I want to leave this for future enhancement.
 
 Currently, what is supported is that all calls must see all the versions
 that will be created. I can create a patch to generate an appropriate error
 here  so that this is made clear.


[Bug other/56955] documentation for attribute malloc contradicts itself

2013-04-26 Thread davidxl at google dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56955



davidxl at google dot com changed:



   What|Removed |Added



 CC||davidxl at google dot com



--- Comment #5 from davidxl at google dot com 2013-04-26 19:16:31 UTC ---

The documentation gives the most strict semantic for the attribute where calloc

is not qualified if NULL is a valid pointer.



However GCC's implementation for the attribute is more relaxed but pessimizes

simple cases:



http://gcc.gnu.org/ml/gcc-patches/2010-02/msg00381.html



David





(In reply to comment #3)

 (In reply to comment #2)

  (In reply to comment #1)

   I think it is talking about the memory returned by malloc/calloc will not 
   point

   to another memory location while realloc can.

  

  I agree that's essentially what it ought to talk about, and the bug is that

  it's talking about something else -- the contents of the pointed-to memory.

 

 Well, it _is_ actually about the content.  There must be no way to compute

 a valid pointer to another object from the contents of the pointed-to

 memory.  So if you initialize the memory to {0, 1, 2, 3, 4 ...} thus

 every possible byte value is somewhere and then do

 

   void *p = (void *)(mem[3]  24 | mem[58]  16 | ...);

 

 then points-to analysis assumes that from the contents of 'mem' you

 can only compute pointers to nothing (NULL).  Technically for targets

 where NULL is a valid poiner to an object calloc () may not be marked

 with malloc.

 

 That is, read it in the way that the code assumes the memory _may_ be

 zero-initialized (but only zero-initialized) or uninitialized.


[Bug gcov-profile/54487] [4.8 Regression] profiledbootstrap broken by r190952

2012-09-11 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54487

--- Comment #19 from davidxl at google dot com 2012-09-11 17:44:29 UTC ---
How much saving do we get by not writing out the 0 entries? With the
proposed change, how less frequent is the problem occuring?

David

On Tue, Sep 11, 2012 at 10:38 AM, Teresa Johnson tejohn...@google.com wrote:
 On Tue, Sep 11, 2012 at 10:29 AM, hjl.tools at gmail dot com
 gcc-bugzi...@gcc.gnu.org wrote:
 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54487

 --- Comment #17 from H.J. Lu hjl.tools at gmail dot com 2012-09-11 
 17:29:15 UTC ---
 Thanks for looking into it.  This is a long standing problem.
 I have seen random profiledbootstrap failures for a long time.

 Thanks for confirming that this has happened prior. Unfortunately the
 addition of the histogram is likely making this more frequent, due to
 the changing summary sizes after merging. One way to deal with this
 for now might be to write all histogram entries (even the 0 ones) into
 the summary to keep the size static.

 Honza, what do you think?

 Teresa


 --
 Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
 --- You are receiving this mail because: ---
 You are on the CC list for the bug.



 --
 Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413


[Bug gcov-profile/54487] [4.8 Regression] profiledbootstrap broken by r190952

2012-09-11 Thread davidxl at google dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54487

--- Comment #21 from davidxl at google dot com 2012-09-11 18:08:26 UTC ---
Assuming the size of histogram for the same file does not vary that
much, is it better to round the size to the next power of 2 -- 60
entries will need print out 64 etc?

David

On Tue, Sep 11, 2012 at 11:04 AM, Teresa Johnson tejohn...@google.com wrote:
 On Tue, Sep 11, 2012 at 10:44 AM, Xinliang David Li davi...@google.com 
 wrote:
 How much saving do we get by not writing out the 0 entries? With the
 proposed change, how less frequent is the problem occuring?

 Let me get back with some stats. Each histogram entry requires 5
 words, and there are a max of 252 entries. In the few cases I checked
 just now, we were printing about 60 entries per summary, with 3
 summaries per gcda file. So printing the whole thing in these cases
 would require 5*(252-60)*3 = 2880 extra words, or 11520 bytes.
 Unfortunately, that is a significant increase over the current sizes
 of those files, which are currently only double or triple that.

 I also need to verify that changing this would reduce the frequency.

 A couple other possibilities since this is not frequent:
 - change the existing error to a warning (as we do under
 flag_profile_correction)
 - after finishing reading the counts, re-read the tag as I am doing in
 my debugging, and if it is no longer valid, throw everything away and
 re-read the file.
 - check the counters after reading each one, and if it is  sum_max,
 ignore it and abort the profile read with a warning but continue
 compiling.

 Obviously the best solution would be to figure out how the lock is
 being lost/ignored and fix that, but that may take some time.

 Teresa


 David

 On Tue, Sep 11, 2012 at 10:38 AM, Teresa Johnson tejohn...@google.com 
 wrote:
 On Tue, Sep 11, 2012 at 10:29 AM, hjl.tools at gmail dot com
 gcc-bugzi...@gcc.gnu.org wrote:
 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54487

 --- Comment #17 from H.J. Lu hjl.tools at gmail dot com 2012-09-11 
 17:29:15 UTC ---
 Thanks for looking into it.  This is a long standing problem.
 I have seen random profiledbootstrap failures for a long time.

 Thanks for confirming that this has happened prior. Unfortunately the
 addition of the histogram is likely making this more frequent, due to
 the changing summary sizes after merging. One way to deal with this
 for now might be to write all histogram entries (even the 0 ones) into
 the summary to keep the size static.

 Honza, what do you think?

 Teresa


 --
 Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
 --- You are receiving this mail because: ---
 You are on the CC list for the bug.



 --
 Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413



 --
 Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413


[Bug testsuite/36440] [4.4 Regression] FAIL: g++.dg/cdce3.C on powerpc-apple-darwin8.5.0

2008-06-06 Thread davidxl at google dot com


--- Comment #2 from davidxl at google dot com  2008-06-06 18:00 ---
(In reply to comment #1)
 The failures disappear with the following patch:
 
 --- /opt/gcc/_gcc_clean/gcc/testsuite/g++.dg/cdce3.C2008-06-05
 08:50:23.0 +0200
 +++ /opt/gcc/gcc-4.4-work/gcc/testsuite/g++.dg/cdce3.C  2008-06-06
 13:50:12.0 +0200
 @@ -1,4 +1,4 @@
 -/* { dg-do  run { target { ! *-*-darwin } } } */
 +/* { dg-do  run { target { ! *-*-darwin* } } } */
  /* { dg-options -O2 -fmath-errno -fdump-tree-cdce-details  -lm } */
  /* { dg-final { scan-tree-dump  cdce3.C:68: note: function call is
 shrink-wrapped into error conditions\. cdce } }*/
  /* { dg-final { scan-tree-dump  cdce3.C:69: note: function call is
 shrink-wrapped into error conditions\. cdce } }*/
 
 (at least on i686-apple-darwin9).
 

I wonder why gcc.dg/cdce1.c and gcc.dg/cdce2.c do not fail in the same way?

David


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36440