From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17305 invoked by alias); 30 Nov 2004 20:57:59 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 17045 invoked from network); 30 Nov 2004 20:57:44 -0000 Received: from unknown (HELO rwcrmhc12.comcast.net) (216.148.227.85) by sourceware.org with SMTP; 30 Nov 2004 20:57:44 -0000 Received: from [10.0.1.2] (h000393256f12.ne.client2.attbi.com[24.61.199.96]) by comcast.net (rwcrmhc12) with SMTP id <2004113020574201400031p8e>; Tue, 30 Nov 2004 20:57:43 +0000 User-Agent: Microsoft-Entourage/11.1.0.040913 Date: Tue, 30 Nov 2004 22:47:00 -0000 Subject: Re: INT_MIN % -1 From: Paul Schlie To: Robert Dewar CC: Message-ID: In-Reply-To: <41ABF8C8.7040108@gnat.com> Mime-version: 1.0 Content-type: text/plain; charset="US-ASCII" Content-transfer-encoding: 7bit X-SW-Source: 2004-11/txt/msg01225.txt.bz2 With reference to the below: I would guess that rather than attempting to expose a check for a / or % by -1 to the compiler, I would assume that it's best handled by the back end during code generations, as the most efficient solution is target specific: - for targets which have hardware / and/or % instruction support and handle things properly, nothing special is required other than a correctly coded .md file. - for targets which have hardware/ and/or % instruction support, but don't handle things properly, it's likely sufficient to incorporate a test for a -1 divisor into the .md description of the operations (which fortunately will likely only minimally affect performance, as / and % functions tend to often be multi-cycle to begin with, if supported at all). - for targets which don't have hardware / and/or % instruction support, it's likely simplest to trasparently incorporate correct behavior into the libgcc2 built-in / and/or % function definitions. Independently, in circumstances where either the dividend or divisor are constants, the middle-end may always choose to eliminate the / or % operations altogether, if it's result can be determined statically. > From: Robert Dewar > >> Paul Schlie wrote: >> >> (where I'm assuming: (-INT_MIN / -1) => -1 isn't reasonably correct or >> necessary, nor is a run-time exception/trap) >> >> Although possibly naive, I'd like to think that the C standard won't be used >> as a crutch, but that GCC may rise above many of the unspecified behaviors, >> and establish instead, well defined logically consistent useful ones, which >> others may aspire to emulate. > > One possibility would be to have an optional divide by zero trap that sets > the right result and continues. Then there is a special compiler switch > that sets up this trap routine if you really really really want this not > very useful marginal behavior (a real division by zero is undefined, so > it is fine to do anything you like). That being said, GNAT (the Ada front > end) does go to the trouble of doing this right. Given the source program: > >> procedure K is >> X, Y : Integer; >> function Id (X : Integer) return Integer is begin return X; end Id; >> begin >> X := Id (Integer'First); >> Y := Id ( - 1); >> X := X mod y; >> end; > > (the Id function is to stop the compiler from doing optimizing value tracing > :-) > > The generated code (-gnatG output) (with checks off to simplifty) looks like: > > procedure k is > x : integer; > y : integer; > > function k__id (x : integer) return integer is > begin > return x; > end k__id; > begin > x := k__id (-16#8000_0000#); > y := k__id (-1); > x := (if y = -1 then 0 else x mod y); > return; > end k; > > The test for y = -1 is precisely to handle this case, and it is only one test. > Note that the cost in Ada is generally smaller than in C, because we know more > about the range of variables. For example, the Ada program: > > procedure K is > X, Y : Integer range -1000 .. +1000; > function Id (X : Integer) return Integer is begin return X; end Id; > begin > X := Id (1); > Y := Id ( - 1); > X := X mod y; > end; > > Does not generate the check for -1, because it knows that X cannot be > Integer'First. >