aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-fnsummary.c44
-rw-r--r--gcc/ipa-inline.c1
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr93940.C38
3 files changed, 76 insertions, 7 deletions
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index b411bc4..d96c8e9 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -503,6 +503,32 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
*ret_nonspec_clause = nonspec_clause;
}
+/* Return true if VRP will be exectued on the function.
+ We do not want to anticipate optimizations that will not happen.
+
+ FIXME: This can be confused with -fdisable and debug counters and thus
+ it should not be used for correctness (only to make heuristics work).
+ This means that inliner should do its own optimizations of expressions
+ that it predicts to be constant so wrong code can not be triggered by
+ builtin_constant_p. */
+
+static bool
+vrp_will_run_p (struct cgraph_node *node)
+{
+ return (opt_for_fn (node->decl, optimize)
+ && !opt_for_fn (node->decl, optimize_debug)
+ && opt_for_fn (node->decl, flag_tree_vrp));
+}
+
+/* Similarly about FRE. */
+
+static bool
+fre_will_run_p (struct cgraph_node *node)
+{
+ return (opt_for_fn (node->decl, optimize)
+ && !opt_for_fn (node->decl, optimize_debug)
+ && opt_for_fn (node->decl, flag_tree_fre));
+}
/* Work out what conditions might be true at invocation of E.
Compute costs for inlined edge if INLINE_P is true.
@@ -594,6 +620,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
/* If we failed to get simple constant, try value range. */
if ((!cst || TREE_CODE (cst) != INTEGER_CST)
+ && vrp_will_run_p (caller)
&& ipa_is_param_used_by_ipa_predicates (callee_pi, i))
{
value_range vr
@@ -609,14 +636,17 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
}
/* Determine known aggregate values. */
- ipa_agg_value_set agg
- = ipa_agg_value_set_from_jfunc (caller_parms_info,
- caller, &jf->agg);
- if (agg.items.length ())
+ if (vrp_will_run_p (caller))
{
- if (!known_aggs_ptr->length ())
- vec_safe_grow_cleared (known_aggs_ptr, count);
- (*known_aggs_ptr)[i] = agg;
+ ipa_agg_value_set agg
+ = ipa_agg_value_set_from_jfunc (caller_parms_info,
+ caller, &jf->agg);
+ if (agg.items.length ())
+ {
+ if (!known_aggs_ptr->length ())
+ vec_safe_grow_cleared (known_aggs_ptr, count);
+ (*known_aggs_ptr)[i] = agg;
+ }
}
}
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 302ce16..f71443f 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -485,6 +485,7 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
else if (check_match (flag_wrapv)
|| check_match (flag_trapv)
|| check_match (flag_pcc_struct_return)
+ || check_maybe_down (optimize_debug)
/* When caller or callee does FP math, be sure FP codegen flags
compatible. */
|| ((caller_info->fp_expressions && callee_info->fp_expressions)
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93940.C b/gcc/testsuite/g++.dg/tree-ssa/pr93940.C
new file mode 100644
index 0000000..b656aad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr93940.C
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Og --coverage -pthread -fdump-tree-optimized -std=c++17" } */
+using uint16_t = unsigned short;
+
+struct a {
+ uint16_t b = 0;
+};
+struct c {
+ short d;
+};
+class e {
+public:
+ void f();
+ void init_session(c);
+};
+
+auto htons = [](uint16_t s) {
+ if (__builtin_constant_p(s)) {
+ return uint16_t(uint16_t(s >> 8) | uint16_t(s << 8));
+ }
+ return uint16_t(uint16_t(s >> 8) | uint16_t(s << 8));
+};
+
+struct g {
+ e h;
+ void i(a k) {
+ h.f();
+ auto j = c();
+ j.d = htons(k.b);
+ h.init_session(j);
+ }
+};
+
+void test() {
+ g().i({});
+}
+
+/* { dg-final { scan-tree-dump-not "builtin_unreachable" "optimized"} } */