Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Mar 2015 05:21:06 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Dimitry Andric <dim@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r279981 - in head: contrib/compiler-rt/lib/builtins lib/libcompiler_rt
Message-ID:  <20150315023356.X977@besplex.bde.org>
In-Reply-To: <201503141240.t2ECeKqP045674@svn.freebsd.org>
References:  <201503141240.t2ECeKqP045674@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 14 Mar 2015, Dimitry Andric wrote:

> Log:
>  =EF=BB=BFPull in r231965 from upstream compiler-rt trunk (by J=C3=B6rg S=
onnenberger):
>
>    Refactor float to integer conversion to share the same code.
>    80bit Intel/PPC long double is excluded due to lacking support
>    for the abstraction. Consistently provide saturation logic.
>    Extend to long double on 128bit IEEE extended platforms.

I hoped that this would fix a longstanding conversion bug, but that bug
is actually for integer to float conversion, and the conversion is inline.

clang can't even convert integer 0 to floating point correctly (when the
integer has type uintmax_t and is variable with value 0, and the rounding
mode is downwards):

X #include <fenv.h>
X #include <stdint.h>
X #include <stdio.h>
X=20
X int
X main(void)
X {
X =09volatile uintmax_t er =3D 0;
X=20
X =09fesetround(FE_DOWNWARD);
X =09printf("%.4f\n", (double)er);
X =09return (0);
X }

clang generates broken inline code giving a result of -0.0000.  It does
a magic conversion involving loading the variable as an integer, shuffling
bits, subtracting a double and adding a double.  The subtraction gives
-0.0 when the rounding mode is downwards.

gcc48 generates apparently-correct inline code.  It does a less magic but
slower conversion involving:
- for values not exceeding INT64_MAX, just cvtsi2sdq
- for values exceeding INT64_MAX, modify er to ((er >> 1) | (er & 1)),
   convert that using cvtsi2sdq, then double the result.

Does this commit fix the differences between the runtime calculations
and compile-time calculations for overflowing cases?  Saturation logic
should do this.  My old test programs (previously last tested in 2004)
show the differences.  Compilers produced much the same garbage in
1994, 2004 and 2015.  Before this commit, they do the following:
- gcc48 saturates at compile time.  Its runtime results are inconsistent
   except for some cases of converting negative values to unsigned:
   - generally, the result is 0x8000000000000000 in bits for 64-bit
     values and 0x80000000 for 32-bit values.  This is the corect x86
     value since it is what is generated on overflow by the hardware.
     Call it IOV.  gcc corrupts even this value:
   - overflowing u_long or long -> (u_long)IOV or (long)IOV, OK
   - overflowing u_long, positive value -> 0
   - overflowing u_long, negative value -> (u_long)IOV, OK, but it is weird
       that negative values overflow to a larger value than positive values=
=2E
   - this is with 64-bit longs on amd64.  For conversions to u_int and int,
     the results are the same (with the the 32-bit IOV), except for the
     weird last result.  Now:
   - overflowing u_int, negative value -> 0.  This is the one case for
     unsigned types where the runtime result is consistent with the compile
     time result.
- clang gives identical results.
gcc was much more inconsistent in 1994.  Its typical behaviour was to
handle u_int by storing an int64_t and discarding the top bits.  uint64_t
is harder to handle and was more broken.

The behaviour is undefined on overflow, so these bugs are less serious
than for converting 0.  I prefer traps on overflow.  Everyone is used
to integer division trapping when the result would be infinite.  x86
hardware makes the trap for this impossible to avoid (but the kernel
could handle the trap and produce an in-band error result like IOV).
Converting FP infinity to integer should do the same.  Unfortunately,
x86 hardware make this trap hard to get efficiently (traps for it
would have to be enabled; then the kernel could produce a signal for
the integer case and emulate the hardware trap handling for the FP
case).

Bruce
From owner-svn-src-all@FreeBSD.ORG  Sat Mar 14 20:40:05 2015
Return-Path: <owner-svn-src-all@FreeBSD.ORG>
Delivered-To: svn-src-all@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
 (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by hub.freebsd.org (Postfix) with ESMTPS id 4185B2B7;
 Sat, 14 Mar 2015 20:40:05 +0000 (UTC)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id 2C2C3E25;
 Sat, 14 Mar 2015 20:40:05 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2EKe4kp075357;
 Sat, 14 Mar 2015 20:40:04 GMT (envelope-from jilles@FreeBSD.org)
Received: (from jilles@localhost)
 by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2EKe4jv075333;
 Sat, 14 Mar 2015 20:40:04 GMT (envelope-from jilles@FreeBSD.org)
Message-Id: <201503142040.t2EKe4jv075333@svn.freebsd.org>
X-Authentication-Warning: svn.freebsd.org: jilles set sender to
 jilles@FreeBSD.org using -f
From: Jilles Tjoelker <jilles@FreeBSD.org>
Date: Sat, 14 Mar 2015 20:40:04 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject: svn commit: r280002 - stable/10/tools/regression/usr.bin/env
X-SVN-Group: stable-10
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-all@freebsd.org
X-Mailman-Version: 2.1.18-1
Precedence: list
List-Id: "SVN commit messages for the entire src tree \(except for &quot;
 user&quot; and &quot; projects&quot; \)" <svn-src-all.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-all/>;
List-Post: <mailto:svn-src-all@freebsd.org>
List-Help: <mailto:svn-src-all-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Sat, 14 Mar 2015 20:40:05 -0000

Author: jilles
Date: Sat Mar 14 20:40:04 2015
New Revision: 280002
URL: https://svnweb.freebsd.org/changeset/base/280002

Log:
  MFC r279722: env: Fix testsuite for additional variables set by sh.

Modified:
  stable/10/tools/regression/usr.bin/env/regress-env.rgdata
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/tools/regression/usr.bin/env/regress-env.rgdata
==============================================================================
--- stable/10/tools/regression/usr.bin/env/regress-env.rgdata	Sat Mar 14 19:22:15 2015	(r280001)
+++ stable/10/tools/regression/usr.bin/env/regress-env.rgdata	Sat Mar 14 20:40:04 2015	(r280002)
@@ -235,9 +235,9 @@ gblenv=OUTSIDEVAR=OutsideValue
    script:/bin/echo "=== set ==="
    script:# drop some environment variables that 'sh' itself sets, and
    script:# then have 'set' print out all remaining environment variables.
-   script:# (can't unset OPTIND, so we use grep to get rid of that)
-   script:unset -v IFS PS1 PS2 PPID
-   script:set | grep -v '^OPTIND=' | sort
+   script:# (can't unset OPTIND/PWD, so we use grep to get rid of those)
+   script:unset -v IFS PS1 PS2 PS4 PPID
+   script:set | grep -Ev '^(OPTIND|PWD)=' | sort
    stdout:=== set ===
    stdout:PATH=/bin:/usr/bin:/Not
    stdout:TESTVAR=SbValue



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150315023356.X977>