aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2023-06-29 22:45:37 +0200
committerJan Hubicka <jh@suse.cz>2023-06-29 22:46:20 +0200
commit9dc18fca431626404b0692c689a2e103666e7adb (patch)
tree6be6a2ec9ebc90eddab30d5f556012b37dba00b6
parent94c71750cdd742a981de33b7fd885f68255b937c (diff)
downloadgcc-9dc18fca431626404b0692c689a2e103666e7adb.zip
gcc-9dc18fca431626404b0692c689a2e103666e7adb.tar.gz
gcc-9dc18fca431626404b0692c689a2e103666e7adb.tar.bz2
Compute ipa-predicates for conditionals involving __builtin_expect_p
std::vector allocator looks as follows: __attribute__((nodiscard)) struct pair * std::__new_allocator<std::pair<unsigned int, unsigned int> >::allocate (struct __new_allocator * const this, size_type __n, const void * D.27753) { bool _1; long int _2; long int _3; long unsigned int _5; struct pair * _9; <bb 2> [local count: 1073741824]: _1 = __n_7(D) > 1152921504606846975; _2 = (long int) _1; _3 = __builtin_expect (_2, 0); if (_3 != 0) goto <bb 3>; [10.00%] else goto <bb 6>; [90.00%] <bb 3> [local count: 107374184]: if (__n_7(D) > 2305843009213693951) goto <bb 4>; [50.00%] else goto <bb 5>; [50.00%] <bb 4> [local count: 53687092]: std::__throw_bad_array_new_length (); <bb 5> [local count: 53687092]: std::__throw_bad_alloc (); <bb 6> [local count: 966367641]: _5 = __n_7(D) * 8; _9 = operator new (_5); return _9; } So there is check for allocated block size being greater than max_size which is wrapper in __builtin_expect. This makes ipa-fnsummary to give up analyzing predicates and it will miss the fact that the two different calls to __throw will be optimized out if __n is larady smaller than 1152921504606846975 which it is after _M_check_len. This patch extends ipa-fnsummary to understand functions that return their parameter. gcc/ChangeLog: PR tree-optimization/109849 * ipa-fnsummary.cc (decompose_param_expr): Skip functions returning its parameter. (set_cond_stmt_execution_predicate): Return early if predicate was constructed. gcc/testsuite/ChangeLog: PR tree-optimization/109849 * gcc.dg/ipa/pr109849.c: New test.
-rw-r--r--gcc/ipa-fnsummary.cc14
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr109849.c27
2 files changed, 41 insertions, 0 deletions
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 78cbb60..53dee8f 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -1516,6 +1516,19 @@ decompose_param_expr (struct ipa_func_body_info *fbi,
if (TREE_CODE (expr) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (expr))
break;
+ stmt = SSA_NAME_DEF_STMT (expr);
+
+ if (gcall *call = dyn_cast <gcall *> (stmt))
+ {
+ int flags = gimple_call_return_flags (call);
+ if (!(flags & ERF_RETURNS_ARG))
+ goto fail;
+ int arg = flags & ERF_RETURN_ARG_MASK;
+ if (arg >= (int)gimple_call_num_args (call))
+ goto fail;
+ expr = gimple_call_arg (stmt, arg);
+ continue;
+ }
if (!is_gimple_assign (stmt = SSA_NAME_DEF_STMT (expr)))
break;
@@ -1664,6 +1677,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
}
}
vec_free (param_ops);
+ return;
}
if (TREE_CODE (op) != SSA_NAME)
diff --git a/gcc/testsuite/gcc.dg/ipa/pr109849.c b/gcc/testsuite/gcc.dg/ipa/pr109849.c
new file mode 100644
index 0000000..09b62f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr109849.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-ipa-inline-details" } */
+void bad (void);
+void
+test(int a)
+{
+ if (__builtin_expect (a>3, 0))
+ {
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ bad ();
+ }
+}
+void
+foo (int a)
+{
+ if (a>0)
+ __builtin_unreachable ();
+ test (a);
+}
+/* { dg-final { scan-ipa-dump "Inlined 2 calls" "inline" } } */
+/* { dg-final { scan-ipa-dump "Inlining test" "inline" } } */