https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122734
Bug ID: 122734
Summary: Hoist loop invariant in presence of exception handling
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: fxue at os dot amperecomputing.com
Target Milestone: ---
Different from vector::operator[](), vector::at() has an extra out-of-bound
check over index when extracting element, and needs to calculate size of the
vector from its start and end addresses, which seem to be loop invariant.
int foo(const std::vector<int> &array, const std::vector<int> &index)
{
int sum = 0;
for (size_t i = 0; i < index.size(); i++)
sum += array.at(index[i]);
return sum;
}
The call to no-return exception handling function does have side effect, but it
might be still legal to hoist these two addresses outside of the loop. Or there
is special point I missed?
int foo (const struct vector & array, const struct vector & index)
{
ptrdiff_t __dif;
ptrdiff_t __dif;
size_t i;
int sum;
int _1;
long unsigned int _2;
int * _7;
int * _8;
value_type _10;
long int _13;
long unsigned int _15;
long unsigned int _16;
const value_type & _17;
long unsigned int _24;
int * _26;
int * _29;
long int _30;
<bb 2> [local count: 40126338]:
_26 = index_6(D)->D.25633._M_impl.D.24944._M_finish;
_29 = index_6(D)->D.25633._M_impl.D.24944._M_start;
_30 = _26 - _29;
__dif_31 = _30 /[ex] 4;
_24 = (long unsigned int) __dif_31;
goto <bb 6>; [100.00%]
<bb 3> [local count: 1034029095]:
_7 = array_9(D)->D.25633._M_impl.D.24944._M_finish; // Could be hoisted?
_8 = array_9(D)->D.25633._M_impl.D.24944._M_start; // Could be hoisted?
_13 = _7 - _8;
_1 = MEM[(const value_type &)_29 + i_33 * 4];
_2 = (long unsigned int) _1;
__dif_14 = _13 /[ex] 4;
_15 = (long unsigned int) __dif_14;
if (_2 >= _15)
goto <bb 4>; [0.00%]
else
goto <bb 5>; [100.00%]
<bb 4> [count: 0]:
std::__throw_out_of_range_fmt ("vector::_M_range_check: __n (which is %zu) >=
this->size() (which is %zu)", _2, _15);
<bb 5> [local count: 1033615486]:
_16 = _1 w* 4;
_17 = _8 + _16;
_10 = *_17;
sum_11 = _10 + sum_32;
i_12 = i_33 + 1;
<bb 6> [local count: 1073312328]:
# sum_32 = PHI <sum_11(5), 0(2)>
# i_33 = PHI <i_12(5), 0(2)>
if (_24 != i_33)
goto <bb 3>; [96.34%]
else
goto <bb 7>; [3.66%]
<bb 7> [local count: 39283232]:
return sum_32;
}