From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Cc: "Jakub Jelinek" <jakub@redhat.com>, "Martin Liška" <mliska@suse.cz>
Subject: Re: [RFC PATCH] Fix pointer diff (was: -fsanitize=pointer-overflow support (PR sanitizer/80998))
Date: Thu, 22 Jun 2017 08:31:00 -0000 [thread overview]
Message-ID: <alpine.LSU.2.20.1706221022200.23185@zhemvz.fhfr.qr> (raw)
In-Reply-To: <alpine.DEB.2.20.1706211657570.2094@stedding.saclay.inria.fr>
On Wed, 21 Jun 2017, Marc Glisse wrote:
> On Wed, 21 Jun 2017, Jakub Jelinek wrote:
>
> > So, I wrote following patch to do the subtraction in unsigned
> > type. It passes bootstrap, but on both x86_64-linux and i686-linux
> > regresses:
> > +FAIL: gcc.dg/torture/pr66178.c -O* (test for excess errors)
> > +FAIL: gcc.dg/tree-ssa/cmpexactdiv-2.c scan-tree-dump-not optimized
> > "minus_expr"
> > +FAIL: g++.dg/tree-ssa/pr21082.C -std=gnu++* (test for excess errors)
> >
> > E.g. in the first testcase we have in the test:
> > static uintptr_t a = ((char *)&&l2-(char *)&&l3)+((char *)&&l1-(char
> > *)&&l2);
> > Without the patch, we ended up with:
> > static uintptr_t a = (uintptr_t) (((long int) &l2 - (long int) &l3) + ((long
> > int) &l1 - (long int) &l2));
> > but with the patch with (the negation in signed type sounds like a folding
> > bug), which is too difficult for the initializer_constant_valid_p* handling:
> > (uintptr_t) (((long unsigned int) -(long int) &l3 - (long unsigned int) &l2)
> > + ((long unsigned int) &l2 + (long unsigned int) &l1));
> > Shall we just xfail that test, or make sure we don't reassociate such
> > subtractions, something different?
>
> Adding to match.pd a few more simple reassoc transformations (like
> (c-b)+(b-a) for instance) that work for both signed and unsigned is on
> my TODO-list, though that may not be enough. Maybe together with fixing
> whatever produced the negation would suffice?
I guess try to fix the negation and see if that magically fixes things...
> > The second failure is on:
> > int f (long *a, long *b, long *c) {
> > __PTRDIFF_TYPE__ l1 = b - a;
> > __PTRDIFF_TYPE__ l2 = c - a;
> > return l1 < l2;
> > }
> > where without the patch during forwprop2 we optimize it
> > using match.pd:
> > /* X - Z < Y - Z is the same as X < Y when there is no overflow. */
> > because we had:
> > b.0_1 = (long int) b_8(D);
> > a.1_2 = (long int) a_9(D);
> > _3 = b.0_1 - a.1_2;
> > c.2_4 = (long int) c_11(D);
> > a.3_5 = (long int) a_9(D);
> > _6 = c.2_4 - a.3_5;
> > _7 = _3 < _6;
> > But with the patch we have:
> > b.0_1 = (long unsigned int) b_9(D);
> > a.1_2 = (long unsigned int) a_10(D);
> > _3 = b.0_1 - a.1_2;
> > _4 = (long int) _3;
> > c.2_5 = (long unsigned int) c_11(D);
> > _6 = c.2_5 - a.1_2;
> > _7 = (long int) _6;
> > _8 = _4 < _7;
> > instead. But that is something we can't generally optimize.
> > So do we need to introduce POINTER_DIFF (where we could still
> > optimize this) or remove the test? If we rely on largest possible
> > array to be half of the VA size - 1 (i.e. where for x > y both being
> > pointers into the same array x - y > 0), then it is a valid optimization
> > of the 2 pointer subtractions, but it is not a valid optimization on
> > comparison of unsigned subtractions cast to signed type.
>
> (this testcase was meant as a simpler version of
> vector.size() < vector.capacity() )
>
> It does indeed seem impossible to do this optimization with the unsigned
> pointer subtraction.
Yep :/ This is the issue with all the non-pointer integer folding
fixes as well -- as soon as we introduce unsigned ops for the fear
of introducing undefined overflow we lose on followup optimization
opportunities.
> If we consider pointers as unsigned, with a subtraction that has a signed
> result with the constraint that overflow is undefined, we cannot model that
> optimally with just the usual signed/unsigned operations, so I am in favor of
> POINTER_DIFF, at least in the long run (together with having a signed second
> argument for POINTER_PLUS, etc). For 64-bit platforms it might have been
> easier to declare that the upper half (3/4 ?) of the address space doesn't
> exist...
I repeatedly thought of POINTER_DIFF_EXPR but adding such a basic tree
code is quite a big job. So we'd have POINTER_DIFF_EXPR take two
pointer typed args and produce ptrdiff_t. What's the advantage of
having this? And yes, I agree that POINTER_PLUS_EXPR should take
ptrdiff_t rather than sizetype offset -- changing one without the
other will lead to awkwardness in required patterns involving
both like (p - q) + q.
As said, it's a big job with likely all sorts of (testsuite) fallout.
> > The third one is
> > if (&a[b] - &a[c] != b - c)
> > link_error();
> > where fold already during generic folding used to be able to cope with it,
> > but now we have:
> > (long int) (((long unsigned int) b - (long unsigned int) c) * 4) /[ex] 4 !=
> > b - c
> > which we don't fold.
>
> Once we have this last expression, we have lost, we need to know that the
> multiplication cannot overflow for this. When the size multiplications are
> done in a signed type in the future (?), it might help.
Not sure where the unsigned multiply comes from -- I guess we fold
it inside the cast ...
> On the other hand, is this an important optimization? I am surprised we are
> only doing this transformation in generic (so some hack in the front-end could
> still work), it shouldn't be hard to implement some subset of
> fold_addr_of_array_ref_difference in match.pd (it is recursive so a complete
> move may be harder). But that would make your patch break even more stuff :-(
It's always the question whether the above testsuite regressions have any
real-world impact of course.
I don't like the idea of not doing foldings condidional on sanitization
too much.
Richard.
next prev parent reply other threads:[~2017-06-22 8:31 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-19 18:25 [RFC PATCH] -fsanitize=pointer-overflow support (PR sanitizer/80998) Jakub Jelinek
2017-06-20 7:41 ` Richard Biener
2017-06-20 8:14 ` Jakub Jelinek
2017-06-20 8:18 ` Richard Biener
2017-06-21 7:58 ` Jakub Jelinek
2017-06-21 8:04 ` Richard Biener
2017-06-21 14:40 ` [RFC PATCH] Fix pointer diff (was: -fsanitize=pointer-overflow support (PR sanitizer/80998)) Jakub Jelinek
2017-06-21 15:17 ` Jakub Jelinek
2017-06-21 16:27 ` Marc Glisse
2017-06-22 8:31 ` Richard Biener [this message]
2017-06-22 9:29 ` Marc Glisse
2017-06-22 9:46 ` Richard Biener
2017-07-01 16:41 ` Marc Glisse
2017-07-03 12:37 ` Richard Biener
2017-10-09 11:01 ` Marc Glisse
2017-10-19 15:11 ` Richard Biener
2017-10-28 13:04 ` Marc Glisse
2017-10-28 17:13 ` Richard Biener
2017-07-04 8:53 ` [RFC PATCH] -fsanitize=pointer-overflow support (PR sanitizer/80998) Jakub Jelinek
2017-06-21 8:00 ` Jakub Jelinek
2017-06-21 8:05 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LSU.2.20.1706221022200.23185@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=mliska@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).