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 " user" and " projects" \)" <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>