On 03/07/2018 03:52 PM, Martin Sebor wrote: > On 03/07/2018 12:37 PM, Jeff Law wrote: >> On 02/26/2018 10:32 AM, Martin Sebor wrote: >>> >>> PR tree-optimization/84526 - ICE in generic_overlap at >>> gcc/gimple-ssa-warn-restrict.c:927 since r257860 >>> >>> >>> gcc/ChangeLog: >>> >>> PR tree-optimization/84526 >>> * gimple-ssa-warn-restrict.c (builtin_memref::set_base_and_offset): >>> Remove dead code. >>> (builtin_access::generic_overlap): Be prepared to handle non-array >>> base objects. >>> >>> gcc/testsuite/ChangeLog: >>> >>> PR tree-optimization/84526 >>> * gcc.dg/Wrestrict-10.c: New test. >>> >>> Index: gcc/gimple-ssa-warn-restrict.c >>> =================================================================== >>> --- gcc/gimple-ssa-warn-restrict.c (revision 257963) >>> +++ gcc/gimple-ssa-warn-restrict.c (working copy) >>> @@ -396,6 +396,9 @@ builtin_memref::set_base_and_offset (tree expr) >>> if (TREE_CODE (expr) == ADDR_EXPR) >>> expr = TREE_OPERAND (expr, 0); >>> >>> + /* Stash the reference for offset validation. */ >>> + ref = expr; >>> + >>> poly_int64 bitsize, bitpos; >>> tree var_off; >>> machine_mode mode; >>> @@ -409,23 +412,33 @@ builtin_memref::set_base_and_offset (tree expr) >>> base = get_inner_reference (expr, &bitsize, &bitpos, &var_off, >>> &mode, &sign, &reverse, &vol); >>> >>> + /* get_inner_reference is not expected to return null. */ >>> + gcc_assert (base != NULL); >>> + >>> poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT); >>> >>> - HOST_WIDE_INT const_off; >>> - if (!base || !bytepos.is_constant (&const_off)) >>> + /* Convert the poly_int64 offset to to offset_int. The offset >>> + should be constant but be prepared for it not to be just in >>> + case. */ >>> + offset_int cstoff; >>> + if (bytepos.is_constant (&cstoff)) >>> { >>> - base = get_base_address (TREE_OPERAND (expr, 0)); >>> - return; >>> + offrange[0] += cstoff; >>> + offrange[1] += cstoff; >>> + >>> + /* Besides the reference saved above, also stash the offset >>> + for validation. */ >>> + if (TREE_CODE (expr) == COMPONENT_REF) >>> + refoff = cstoff; >>> } >>> + else >>> + offrange[1] += maxobjsize; >> So is this assignment to offrange[1] really correct? >> >> ISTM that it potentially overflows (relative to MAXOBJSIZE) and that >> you'd likely be better off just assigning offrange[1] to MAXOBJSIZE. >> >> Or alternately signal to the callers that we can't really analyze the >> memory address and inhibit further analysis of the potential overlap of >> the objects. > > The offsets are stored in offset_int and there is code to deal > with values outside the [-MAXOBJSIZE, MAXOBJSIZE] range, either > by capping them to the bounds of the array/object being accessed > if it's known, or to the MAXOBJSIZE range. There are a number of > places where offsets with unknown values are being added together > and where their sum might end up exceeding that range (e.g., when > dealing with multiple offsets, each in some range) but as long > as the offsets are only added and not multiplied they should never > overflow offset_int. It would be okay to assign MAXOBJSIZE here > instead of adding it, but there are other places with the same > addition (see the bottom of builtin_memref::extend_offset_range) > so doing it here alone would be inconsistent. OK. Thanks for explaining.
> >>> @@ -918,12 +924,18 @@ builtin_access::generic_overlap () >>> if (!overlap_certain) >>> { >>> if (!dstref->strbounded_p && !depends_p) >>> + /* Memcpy only considers certain overlap. */ >>> return false; >>> >>> /* There's no way to distinguish an access to the same member >>> of a structure from one to two distinct members of the same >>> structure. Give up to avoid excessive false positives. */ >>> - tree basetype = TREE_TYPE (TREE_TYPE (dstref->base)); >>> + tree basetype = TREE_TYPE (dstref->base); >>> + >>> + if (POINTER_TYPE_P (basetype) >>> + || TREE_CODE (basetype) == ARRAY_TYPE) >>> + basetype = TREE_TYPE (basetype); >>> + >>> if (RECORD_OR_UNION_TYPE_P (basetype)) >>> return false; >>> } >> This is probably fairly reasonable. My only concern would be that we >> handle multi-dimensional arrays correctly. Do you need to handle >> ARRAY_TYPEs with a loop? > > Yes, good catch, thanks! It's unrelated to this bug (the ICE) but > it seems simple enough to handle at the same time so I've added > the loop and a test to verify it works as expected. > >> I do have a more general concern. Given that we walk backwards through >> pointer casts and ADDR_EXPRs we potentially lose information. For >> example we might walk backwards through a cast from a small array to a >> larger array type. Agreed. Thanks for fixing this as well. Agreed it seems simple enough to go ahead and handle now. >> >> Thus later we use the smaller array type when computing the bounds and >> subsequent offset from BASE. This could lead to a missed warning as the >> computed offset would be too small. > > There are many false negatives here. A lot of those I noticed > during testing are because of limitations in the strlen pass > (I must have raised a dozen bugs to track and, hopefully, fix > in stage 1). There are also deficiencies in the restrict pass > itself. For instance, using builtin_object_size to compute > the size of member arrays leads to many because bos computes > the size of the larger object. It's on my to do list to open > bugs for all these false negatives irrespective of the strlen > limitations as a reminder to add test cases for the former. Understood. I should have been clearer that I don't think we necessarily have to address the false negatives right now. Just that this is a potential source of them. > >> I'm inclined to ack after fixing offrange[1] computation noted above as >> I don't think the patch makes things any worse. As I noted in a prior >> message, I don't see concerns with consistency of BASE that Jakub sees here. >> > > Attached is a revision with the loop. I didn't make any > changes to the offrange[1] computation. If you want me to > change it wholesale for all the uses let me know, but I would > prefer to do it in a separate change, after fixing the ICE. > > Martin > > > gcc-84526.diff > > > PR tree-optimization/84526 - ICE in generic_overlap at > gcc/gimple-ssa-warn-restrict.c:927 since r257860 > > gcc/ChangeLog: > > PR tree-optimization/84526 > * gimple-ssa-warn-restrict.c (builtin_memref::set_base_and_offset): > Remove dead code. > (builtin_access::generic_overlap): Be prepared to handle non-array > base objects. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/84526 > * gcc.dg/Wrestrict-10.c: New test. > * gcc.dg/Wrestrict-11.c: New test. OK. I think Richard S. had some follow-up issues that didn't affect correctness/behavior. Those clean ups are pre-approved. Given we've seen a few instances pop up in Fedora, I'm going to go ahead and commit now. At the least it'll stop duplicates in our BZ and if Jakub is spinning a new Fedora release over the weekend, it'd get picked up for Fedora as well. Jeff