From 6a00bf6bceed6c8c9c4a47a8d39f329632b4e856 Mon Sep 17 00:00:00 2001 From: rguenth Date: Mon, 18 Nov 2013 15:25:05 +0000 Subject: [PATCH] 2013-11-18 Richard Biener 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204966 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 13 ++++++++++ gcc/passes.def | 2 +- gcc/testsuite/ChangeLog | 10 ++++++++ gcc/testsuite/gcc.dg/builtin-object-size-14.c | 28 ++++++++++++++++++++ gcc/testsuite/gcc.dg/builtin-object-size-8.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-14gf.c | 10 ++++---- gcc/testsuite/gcc.dg/strlenopt-1f.c | 4 +-- gcc/testsuite/gcc.dg/strlenopt-4gf.c | 12 ++++----- gcc/tree-object-size.c | 37 ++++++++++++++++----------- gcc/tree-ssa-sccvn.c | 12 +++++++-- 10 files changed, 98 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-14.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7220961..f10564b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-11-18 Richard Biener + + 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 * tree.h (tree_to_uhwi): Return an unsigned HOST_WIDE_INT. diff --git a/gcc/passes.def b/gcc/passes.def index 8d8dd80..49faf25 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e5e9ecb..909942b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2013-11-18 Richard Biener + + 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 * gnat.dg/volatile11.adb: New test. diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-14.c b/gcc/testsuite/gcc.dg/builtin-object-size-14.c new file mode 100644 index 0000000..085011e --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-object-size-14.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-8.c b/gcc/testsuite/gcc.dg/builtin-object-size-8.c index 7af64d3..f2d88f9 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-8.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-8.c @@ -1,4 +1,4 @@ -/* { dg-do run { xfail *-*-* } } */ +/* { dg-do run } */ /* { dg-options "-O2" } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/strlenopt-14gf.c b/gcc/testsuite/gcc.dg/strlenopt-14gf.c index 6e5c9b0..8b78538 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14gf.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c index e0a2c92..50c5f91 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-1f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-4gf.c b/gcc/testsuite/gcc.dg/strlenopt-4gf.c index 743066f..e176236 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4gf.c @@ -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" } } */ diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 51a5d59..8dcd2aa 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -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)); } } } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 8742e26..26bb190 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -760,7 +760,7 @@ copy_reference_ops_from_ref (tree ref, vec *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 *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; } } -- 2.7.4