From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id A3315385700A for ; Mon, 9 Nov 2020 07:31:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A3315385700A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rguenther@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 85377ABAE; Mon, 9 Nov 2020 07:31:15 +0000 (UTC) Date: Mon, 9 Nov 2020 08:31:15 +0100 (CET) From: Richard Biener Sender: rguenther@c653.arch.suse.de To: Jan Hubicka cc: gcc@gcc.gnu.org Subject: Re: Definition of EAF_NOESCAPE and fnspec strings In-Reply-To: <20201108124711.GD65107@kam.mff.cuni.cz> Message-ID: References: <20201108124711.GD65107@kam.mff.cuni.cz> User-Agent: Alpine 2.21 (LSU 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2020 07:31:19 -0000 On Sun, 8 Nov 2020, Jan Hubicka wrote: > Hi, > I implemented simple propagation of EAF arguments for ipa-modref (that is not > hard to do). My main aim was to detect cases where THIS parameter does not > escape but is used to read/write pointed to memory. This is meant to > avoid poor code produced when we i.e. offline destructors on cold path. > > Unfortunately detecting EAF_NOESCAPE for such parameters breaks. This is already > visible on memcpy if we let it to be be handled via its fnspec > attribute. If I disable special handling in structalias: > > diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c > index a4832b75436..2b614913b57 100644 > --- a/gcc/tree-ssa-structalias.c > +++ b/gcc/tree-ssa-structalias.c > @@ -4389,7 +4389,6 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t) > case BUILT_IN_STRCPY: > case BUILT_IN_STRNCPY: > case BUILT_IN_BCOPY: > - case BUILT_IN_MEMCPY: > case BUILT_IN_MEMMOVE: > case BUILT_IN_MEMPCPY: > case BUILT_IN_STPCPY: > > In the following testcase we miss the fact that memcpy may merge i4p PTA > set to i3p. > > extern void exit (int); > extern void abort (void); > int size = 8; > > int main (void) > { > int i3 = -1, i4 = 55; > int *i3p = &i3; > int *i4p = &i4; > > memcpy(&i3p, &i4p, size); > if (i3p != i4p) > abort (); > exit (0); > } > > This seems to be documented for some degree: > > /* Add *tem = nonlocal, do not add *tem = callused as > EAF_NOESCAPE parameters do not escape to other parameters > and all other uses appear in NONLOCAL as well. */ > > But it also means that some of our FNSPECs are wrong now. I wonder if we can > split this porperty to two different flags like EAF_NOEASCAPE and > EAF_INDIRECT_NOESCAPE? Note that EAF_NOESCAPE allows "escaping" to the return value (see handle_rhs_call). I guess for simplicity we could allow escaping of not escaped but USED params to other written to params. I think we also don't handle "escaping" of a parameter indirectly to itself, thus int i; int *p = &i; int **q = &p; foo (&q); if (*q != i) abort (); and foo (int ***p) { *p = **p; } or so with foos param EAF_NOESCAPE (but not EAF_DIRECT). Splitting up EAF_NOESCAPE makes it quite difficult to understand. Arguably explicit handling of memcpy and friends _does_ pay off for points-to analysis since I'd say modelling all possible and useful things in fnspec would make it a monster ... you'd basically want to have a way to specify additional constraints in the fnspec itself, like *1 = *2, but then also distinguish points-to effects from may-alias ones. I wonder if we should teach the GIMPLE FE to parse 'fn spec' so we can write unit tests for the attribute ... or maybe simply add this to the __GIMPLE spec string. > Auto-detecting EAF_INDIRECT_NOESCAPE seems bit harder at least assuming > that any read can actually load few bits of pointer possibly written > there beause if simple member functions accesses values pointer by THIS > and return them we lose a track if the returned value is an escape point > I would say. > > The difference in constraints are: > > --- good/a.c.035t.ealias 2020-11-08 13:34:04.397499515 +0100 > +++ a.c.035t.ealias 2020-11-08 13:39:15.483438469 +0100 > @@ -106,7 +106,15 @@ > size = NONLOCAL > size.0_1 = size > _2 = size.0_1 > -i3p = i4p > +callarg(18) = &i3p > +callarg(18) = callarg(18) + UNKNOWN > +CALLUSED(16) = callarg(18) > +CALLCLOBBERED(17) = callarg(18) > +*callarg(18) = NONLOCAL > +callarg(19) = &i4p > +callarg(19) = callarg(19) + UNKNOWN > +CALLUSED(16) = callarg(19) > +ESCAPED = _2 > i3p.1_3 = i3p > i4p.2_4 = i4p > ESCAPED = &NULL > > ... > > Call clobber information > > -ESCAPED, points-to NULL, points-to vars: { } > +ESCAPED, points-to non-local, points-to NULL, points-to vars: { } > > Flow-insensitive points-to information > > -i3p.1_3, points-to NULL, points-to vars: { D.1947 D.1948 } > +i3p.1_3, points-to non-local, points-to escaped, points-to NULL, points-to vars: { D.1947 } > i4p.2_4, points-to NULL, points-to vars: { D.1948 } > > main () > > Honza > -- Richard Biener SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend