diff options
author | Jan Hubicka <jh@suse.cz> | 2023-06-29 22:45:37 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2023-06-29 22:46:20 +0200 |
commit | 9dc18fca431626404b0692c689a2e103666e7adb (patch) | |
tree | 6be6a2ec9ebc90eddab30d5f556012b37dba00b6 | |
parent | 94c71750cdd742a981de33b7fd885f68255b937c (diff) | |
download | gcc-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.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/pr109849.c | 27 |
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" } } */ |