aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-object-size.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-07-13 11:04:22 +0200
committerJakub Jelinek <jakub@redhat.com>2021-07-13 11:04:22 +0200
commitdddb6ffdc5c25264dd75ad82dad8e48a0718d2d9 (patch)
tree35d686b02d359687426fa3ecc944083704d7a3cd /gcc/tree-object-size.c
parent42f10ba5b57250506d69a0391ea7771c843ea286 (diff)
downloadgcc-dddb6ffdc5c25264dd75ad82dad8e48a0718d2d9.zip
gcc-dddb6ffdc5c25264dd75ad82dad8e48a0718d2d9.tar.gz
gcc-dddb6ffdc5c25264dd75ad82dad8e48a0718d2d9.tar.bz2
passes: Fix up subobject __bos [PR101419]
The following testcase is miscompiled, because VN during cunrolli changes __bos argument from address of a larger field to address of a smaller field and so __builtin_object_size (, 1) then folds into smaller value than the actually available size. copy_reference_ops_from_ref has a hack for this, but it was using cfun->after_inlining as a check whether the hack can be ignored, and cunrolli is after_inlining. This patch uses a property to make it exact (set at the end of objsz pass that doesn't do insert_min_max_p) and additionally based on discussions in the PR moves the objsz pass earlier after IPA. 2021-07-13 Jakub Jelinek <jakub@redhat.com> Richard Biener <rguenther@suse.de> PR tree-optimization/101419 * tree-pass.h (PROP_objsz): Define. (make_pass_early_object_sizes): Declare. * passes.def (pass_all_early_optimizations): Rename pass_object_sizes there to pass_early_object_sizes, drop parameter. (pass_all_optimizations): Move pass_object_sizes right after pass_ccp, drop parameter, move pass_post_ipa_warn right after that. * tree-object-size.c (pass_object_sizes::execute): Rename to... (object_sizes_execute): ... this. Add insert_min_max_p argument. (pass_data_object_sizes): Move after object_sizes_execute. (pass_object_sizes): Likewise. In execute method call object_sizes_execute, drop set_pass_param method and insert_min_max_p non-static data member and its initializer in the ctor. (pass_data_early_object_sizes, pass_early_object_sizes, make_pass_early_object_sizes): New. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Use (cfun->curr_properties & PROP_objsz) instead of cfun->after_inlining. * gcc.dg/builtin-object-size-10.c: Pass -fdump-tree-early_objsz-details instead of -fdump-tree-objsz1-details in dg-options and adjust names of dump file in scan-tree-dump. * gcc.dg/pr101419.c: New test.
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r--gcc/tree-object-size.c114
1 files changed, 73 insertions, 41 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 13be7f4..744748d 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -1304,45 +1304,6 @@ fini_object_sizes (void)
}
}
-
-/* Simple pass to optimize all __builtin_object_size () builtins. */
-
-namespace {
-
-const pass_data pass_data_object_sizes =
-{
- GIMPLE_PASS, /* type */
- "objsz", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- ( PROP_cfg | PROP_ssa ), /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_object_sizes : public gimple_opt_pass
-{
-public:
- pass_object_sizes (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_object_sizes, ctxt), insert_min_max_p (false)
- {}
-
- /* opt_pass methods: */
- opt_pass * clone () { return new pass_object_sizes (m_ctxt); }
- void set_pass_param (unsigned int n, bool param)
- {
- gcc_assert (n == 0);
- insert_min_max_p = param;
- }
- virtual unsigned int execute (function *);
-
- private:
- /* Determines whether the pass instance creates MIN/MAX_EXPRs. */
- bool insert_min_max_p;
-}; // class pass_object_sizes
-
/* Dummy valueize function. */
static tree
@@ -1351,8 +1312,8 @@ do_valueize (tree t)
return t;
}
-unsigned int
-pass_object_sizes::execute (function *fun)
+static unsigned int
+object_sizes_execute (function *fun, bool insert_min_max_p)
{
basic_block bb;
FOR_EACH_BB_FN (bb, fun)
@@ -1453,6 +1414,38 @@ pass_object_sizes::execute (function *fun)
return 0;
}
+/* Simple pass to optimize all __builtin_object_size () builtins. */
+
+namespace {
+
+const pass_data pass_data_object_sizes =
+{
+ GIMPLE_PASS, /* type */
+ "objsz", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ PROP_objsz, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_object_sizes : public gimple_opt_pass
+{
+public:
+ pass_object_sizes (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_object_sizes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_object_sizes (m_ctxt); }
+ virtual unsigned int execute (function *fun)
+ {
+ return object_sizes_execute (fun, false);
+ }
+}; // class pass_object_sizes
+
} // anon namespace
gimple_opt_pass *
@@ -1460,3 +1453,42 @@ make_pass_object_sizes (gcc::context *ctxt)
{
return new pass_object_sizes (ctxt);
}
+
+/* Early version of pass to optimize all __builtin_object_size () builtins. */
+
+namespace {
+
+const pass_data pass_data_early_object_sizes =
+{
+ GIMPLE_PASS, /* type */
+ "early_objsz", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_early_object_sizes : public gimple_opt_pass
+{
+public:
+ pass_early_object_sizes (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_early_object_sizes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual unsigned int execute (function *fun)
+ {
+ return object_sizes_execute (fun, true);
+ }
+}; // class pass_object_sizes
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_early_object_sizes (gcc::context *ctxt)
+{
+ return new pass_early_object_sizes (ctxt);
+}