https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108385
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |12.3
Blocks| |85316
CC| |aldyh at gcc dot gnu.org,
| |amacleod at redhat dot com
Keywords| |missed-optimization
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
<bb 2> [local count: 118111600]:
_1 = params_3(D)->ptrType1;
err = anotherMethod (_1); [return slot optimization]
_31 = err._size;
_32 = (sizetype) _31;
iftmp.0_33 = _32 * 8;
_34 = operator new [] (iftmp.0_33);
<bb 3> [local count: 118111600]:
aItr_35 = err._data;
if (iftmp.0_33 != 0)
goto <bb 4>; [89.00%]
else
goto <bb 7>; [11.00%]
<bb 4> [local count: 105119324]:
__builtin_memcpy (_34, aItr_35, iftmp.0_33);
sum_9 = MEM[(double *)_34];
_38 = _34 + iftmp.0_33;
if (_34 != _38)
goto <bb 5>; [89.00%]
else
goto <bb 6>; [11.00%]
(gdb) p debug_bb_n (6)
<bb 6> [local count: 1271944]:
operator delete [] (_38);
goto <bb 10>; [100.00%]
there's a missed optimization. We are on the path iftmp.0_33 != 0 so
the _34 != _38 check should evaluate to true and BB 6 with the deallocation
be unreachable.
The "fix" on trunk looks bogus and more like a missed optimization somewhere
causing this not to be exposed.
At VRP2 time we see
<bb 3> [local count: 118111600]:
aItr_35 = err._data;
endp_39 = aItr_35 + iftmp.0_33;
if (aItr_35 != endp_39)
and
_38 = _34 + iftmp.0_33;
if (_38 != _34)
it looks like we fail to infer a range for iftmp.0_33 from the BB3 condition
and fail to use that to simplify the later check.
The first check is rewritten to iftmp.0_33 != 0 by forwprop4 but that
doesn't rewrite the later check, likely because _39 has a single-use
but _38 does not. On trunk both are rewritten to iftmp.0_33 != 0 by
(simplify
(op:c (nop_convert?@3 (pointer_plus@2 (convert1? @0) @1)) (convert2? @0))
(if (tree_nop_conversion_p (TREE_TYPE (@2), TREE_TYPE (@0))
&& tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))
&& (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))))
(op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
because _38 there _is_ a single use, likely due to that missed optimization
(jump threading?).
As said, the question is why we do not derive a range for iftmp.0_33 here
("here" is the minF function). The dumps say on trunk
=========== BB 3 ============
Imports: iftmp.0_33 aItr_35
Exports: iftmp.0_33 aItr_35 endp_39
endp_39 : iftmp.0_33(I) aItr_35(I)
iftmp.0_33 [irange] long unsigned int [0, 34359738360] NONZERO 0x7fffffff8
Equivalence set : [endp_39]
Equivalence set : [aItr_35]
<bb 3> [local count: 118111600]:
aItr_35 = err._data;
endp_39 = aItr_35 + iftmp.0_33;
if (aItr_35 != endp_39)
goto <bb 4>; [89.00%]
else
goto <bb 7>; [11.00%]
3->4 (T) iftmp.0_33 : [irange] long unsigned int [0, 34359738360] NONZERO
0x7fffffff8
3->7 (F) iftmp.0_33 : [irange] long unsigned int [0, 34359738360] NONZERO
0x7fffffff8
huh, so why for aItr_35 == endp_39 is the iftmp.0_33 range not zero?!
=========== BB 4 ============
Imports: iftmp.0_33 _34
Exports: _16 iftmp.0_33 _34
_15 : aItr_35(I)
_16 : iftmp.0_33(I) _34(I)
_47 : endp_39(I)
_15 [irange] unsigned long [1, +INF]
iftmp.0_33 [irange] long unsigned int [0, 34359738360] NONZERO 0x7fffffff8
aItr_35 [irange] double * [1, +INF]
endp_39 [irange] double * VARYING
Equivalence set : [sum_9]
Equivalence set : [_16]
Partial equiv (_15 pe64 aItr_35)
Partial equiv (_47 pe64 endp_39)
Relational : (aItr_35 != endp_39)
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85316
[Bug 85316] [meta-bug] VRP range propagation missed cases