[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-18 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

--- Comment #6 from Richard Biener rguenth at gcc dot gnu.org ---
Author: rguenth
Date: Mon Nov 18 15:25:05 2013
New Revision: 204966

URL: http://gcc.gnu.org/viewcvs?rev=204966root=gccview=rev
Log:
2013-11-18  Richard Biener  rguent...@suse.de

PR tree-optimization/59125
PR tree-optimization/54570
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): When inlining
is not complete do not treat component-references with offset zero
but different fields as equal.
* tree-object-size.c: Include tree-phinodes.h and ssa-iterators.h.
(compute_object_sizes): Apply TLC.  Propagate the constant
results into all uses and fold their stmts.
* passes.def (pass_all_optimizations): Move pass_object_sizes
after the first pass_forwprop and before pass_fre.

* gcc.dg/builtin-object-size-8.c: Un-xfail.
* gcc.dg/builtin-object-size-14.c: New testcase.
* gcc.dg/strlenopt-14gf.c: Adjust.
* gcc.dg/strlenopt-1f.c: Likewise.
* gcc.dg/strlenopt-4gf.c: Likewise.

Added:
trunk/gcc/testsuite/gcc.dg/builtin-object-size-14.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/passes.def
trunk/gcc/testsuite/ChangeLog
trunk/gcc/testsuite/gcc.dg/builtin-object-size-8.c
trunk/gcc/testsuite/gcc.dg/strlenopt-14gf.c
trunk/gcc/testsuite/gcc.dg/strlenopt-1f.c
trunk/gcc/testsuite/gcc.dg/strlenopt-4gf.c
trunk/gcc/tree-object-size.c
trunk/gcc/tree-ssa-sccvn.c


[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-15 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

Richard Biener rguenth at gcc dot gnu.org changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #4 from Richard Biener rguenth at gcc dot gnu.org ---
Hack to disable the CSE for the relevant cases (which I think are
not-offsetting COMPONENT_REFs):

Index: gcc/tree-ssa-sccvn.c
===
--- gcc/tree-ssa-sccvn.c(revision 204787)
+++ gcc/tree-ssa-sccvn.c(working copy)
@@ -759,7 +759,7 @@ copy_reference_ops_from_ref (tree ref, v
 }

   /* For non-calls, store the information that makes up the address.  */
-
+  tree orig = ref;
   while (ref)
 {
   vn_reference_op_s temp;
@@ -809,7 +809,9 @@ copy_reference_ops_from_ref (tree ref, v
+ tree_to_double_int (bit_offset)
.rshift (BITS_PER_UNIT == 8
   ? 3 : exact_log2 (BITS_PER_UNIT));
-   if (off.fits_shwi ())
+   if (off.fits_shwi ()
+(TREE_CODE (orig) != ADDR_EXPR
+   || !off.is_zero ()))
  temp.off = off.low;
  }
  }

regresses for example

struct s { union { int i; char c[8]; } u; short x; };

char *foo (int b, struct s *p)
{
  int *p1;
  char *p2;
  if (b)
p1 = p-u.i;
  p2 = p-u.c;
  return p2 + *p1;
}

which we then only PRE on the RTL level.  Basically we won't treat those
addresses as equal anymore.

Unfortunately the object-size pass runs quite late so even the 2nd FRE
is already finished (and I think first_instance doesn't work for passes
that are also run during early opts).  I'd say cfun-after_inlining
should work but it won't because object-size is so late.

I don't like moving passes around on the branch, but well ... we'd move
it right after the forwprop run after inlining.

I'm going to test that for trunk now (I still hate how objsize works and
how we want it run so late).


[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-15 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

--- Comment #5 from Richard Biener rguenth at gcc dot gnu.org ---
Related bug is PR54570.


[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-14 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

Richard Biener rguenth at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |ASSIGNED
   Last reconfirmed||2013-11-14
  Component|c   |middle-end
   Target Milestone|--- |4.8.3
Summary|[4.8 regression] gcc|[4.8/4.9 Regression] gcc
   |triggers wrong strncpy_chk  |triggers wrong strncpy_chk
 Ever confirmed|0   |1

--- Comment #1 from Richard Biener rguenth at gcc dot gnu.org ---
Confirmed.  I think we have a similar dup for this that shows the opposite
(missed check).

We CSE the addresses u.vi[0] and u.all[0] resulting in

  bb 2:
  _2 = u_1(D)-D.2172.vi;
  __builtin_strncpy (vi, _2, 8);
  _5 = u_1(D)-D.2172.pi;
  __builtin_strncpy (pi, _5, 16);
  _10 = __builtin_object_size (_2, 1);
  __builtin___strncpy_chk (_2, AbcdefghAbcdefghijklmnopAbcd, 28, _10);

and thus object-size computation going havoc.  The objsz pass reads
too much into the structure of addresses.

We can mitigate this somewhat by folding object sizes early more aggressively
but in this case, when we don't want to fold to 'unknown' too early (like
for this case, where u-all has unknown size as trailing array), it does not
help (we want to wait for an inlining eventually turing 'u' into the address
of a real object to constrain u-all further).

There are opposite desires at work here - the desires to optimize the
program to get more precise 'objects' and the desire to optimize not too much
to confuse the object size computation.


[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-14 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

--- Comment #2 from Richard Biener rguenth at gcc dot gnu.org ---
We already re-fold whenever we fold the object-size stmt via fold_stmt looking
up the def of the address - inlining for example triggers this.  We'd later
pick up more opportunities if we'd enhance forwprop for this for example with:

@@ -1002,6 +1003,22 @@ forward_propagate_addr_expr (tree name,
   bool result;
   tree use_rhs;

+  /* If the use is a __builtin_object_size call then try folding it.  */
+  if (gimple_call_builtin_p (use_stmt, BUILT_IN_OBJECT_SIZE))
+   {
+ tree res = fold_builtin_object_size (rhs,
+  gimple_call_arg (use_stmt, 1));
+ if (res
+  TREE_CODE (res) == INTEGER_CST
+  !integer_all_onesp (res))
+   {
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+ update_call_from_tree (gsi, res);
+ update_stmt (gsi_stmt (gsi));
+ continue;
+   }
+   }
+
   /* If the use is not in a simple assignment statement, then
 there is nothing we can do.  */
   if (gimple_code (use_stmt) != GIMPLE_ASSIGN)

but it does not help this testcase as explained, but it helps the following
one:

#include string.h
struct s {
union u {
struct {
char vi[8];
char pi[16];
};
char all[8+16+4];
} u;
int x;
};
void f(struct s *s)
{
  char vi[8+1];
  char pi[16+1];
  strncpy(vi, s-u.vi, sizeof(s-u.vi));
  strncpy(s-u.all, AbcdefghAbcdefghijklmnopAbcd, sizeof(s-u.all));
}


[Bug middle-end/59125] [4.8/4.9 Regression] gcc triggers wrong strncpy_chk

2013-11-14 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59125

--- Comment #3 from Richard Biener rguenth at gcc dot gnu.org ---
It doesn't work that easily.  But we could refine a folding result without
actually doing the folding by adding an additional argument to the builtin
which serves as a (sofar) known maximum/minimum value.