re PR middle-end/59125 (gcc triggers wrong strncpy_chk)

2013-11-18  Richard Biener  <rguenther@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.

From-SVN: r204966
This commit is contained in:
Richard Biener 2013-11-18 15:25:05 +00:00 committed by Richard Biener
parent 7d362f6c2b
commit 1eadb567ef
10 changed files with 98 additions and 32 deletions

View file

@ -1,3 +1,16 @@
2013-11-18 Richard Biener <rguenther@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.
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* tree.h (tree_to_uhwi): Return an unsigned HOST_WIDE_INT.

View file

@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
form if possible. */
NEXT_PASS (pass_phiprop);
NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_object_sizes);
/* pass_build_alias is a dummy pass that ensures that we
execute TODO_rebuild_alias at this point. */
NEXT_PASS (pass_build_alias);
@ -185,7 +186,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_dce);
NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_phiopt);
NEXT_PASS (pass_object_sizes);
NEXT_PASS (pass_strlen);
NEXT_PASS (pass_ccp);
/* After CCP we rewrite no longer addressed locals into SSA

View file

@ -1,3 +1,13 @@
2013-11-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/59125
PR tree-optimization/54570
* 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.
2013-11-18 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/volatile11.adb: New test.

View file

@ -0,0 +1,28 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
extern void abort (void);
extern char *strncpy(char *, const char *, __SIZE_TYPE__);
union u {
struct {
char vi[8];
char pi[16];
};
char all[8+16+4];
};
void __attribute__((noinline,noclone))
f(union u *u)
{
char vi[8+1];
__builtin_strncpy(vi, u->vi, sizeof(u->vi));
if (__builtin_object_size (u->all, 1) != -1)
abort ();
}
int main()
{
union u u;
f (&u);
return 0;
}

View file

@ -1,4 +1,4 @@
/* { dg-do run { xfail *-*-* } } */
/* { dg-do run } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;

View file

@ -11,14 +11,14 @@
memcpy. */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 3 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */

View file

@ -6,12 +6,12 @@
#include "strlenopt-1.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */

View file

@ -7,13 +7,13 @@
#include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 5 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */

View file

@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssanames.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
struct object_size_info
{
@ -1205,16 +1207,9 @@ compute_object_sizes (void)
gimple_stmt_iterator i;
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
tree callee, result;
tree result;
gimple call = gsi_stmt (i);
if (gimple_code (call) != GIMPLE_CALL)
continue;
callee = gimple_call_fndecl (call);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
if (!gimple_call_builtin_p (call, BUILT_IN_OBJECT_SIZE))
continue;
init_object_sizes ();
@ -1243,20 +1238,32 @@ compute_object_sizes (void)
continue;
}
gcc_assert (TREE_CODE (result) == INTEGER_CST);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Simplified\n ");
print_gimple_stmt (dump_file, call, 0, dump_flags);
fprintf (dump_file, " to ");
print_generic_expr (dump_file, result, 0);
fprintf (dump_file, "\n");
}
if (!update_call_from_tree (&i, result))
gcc_unreachable ();
tree lhs = gimple_call_lhs (call);
if (!lhs)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
/* Propagate into all uses and fold those stmts. */
gimple use_stmt;
imm_use_iterator iter;
FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
{
fprintf (dump_file, "to\n ");
print_gimple_stmt (dump_file, gsi_stmt (i), 0, dump_flags);
fprintf (dump_file, "\n");
use_operand_p use_p;
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
SET_USE (use_p, result);
gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
fold_stmt (&gsi);
update_stmt (gsi_stmt (gsi));
}
}
}

View file

@ -760,7 +760,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
}
/* For non-calls, store the information that makes up the address. */
tree orig = ref;
while (ref)
{
vn_reference_op_s temp;
@ -810,7 +810,15 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
+ 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 ()
/* Probibit value-numbering zero offset components
of addresses the same before the pass folding
__builtin_object_size had a chance to run
(checking cfun->after_inlining does the
trick here). */
&& (TREE_CODE (orig) != ADDR_EXPR
|| !off.is_zero ()
|| cfun->after_inlining))
temp.off = off.low;
}
}