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.