From owner-svn-src-all@freebsd.org Tue Nov 26 22:01:10 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 642791C2ACF; Tue, 26 Nov 2019 22:01:10 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47MyXQ1B91z4K9H; Tue, 26 Nov 2019 22:01:10 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E8A4338AD; Tue, 26 Nov 2019 22:01:09 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xAQM19Gn013608; Tue, 26 Nov 2019 22:01:09 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAQM19rt013607; Tue, 26 Nov 2019 22:01:09 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201911262201.xAQM19rt013607@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Tue, 26 Nov 2019 22:01:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355120 - head/lib/msun/src X-SVN-Group: head X-SVN-Commit-Author: dim X-SVN-Commit-Paths: head/lib/msun/src X-SVN-Commit-Revision: 355120 X-SVN-Commit-Repository: base 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.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Nov 2019 22:01:10 -0000 Author: dim Date: Tue Nov 26 22:01:09 2019 New Revision: 355120 URL: https://svnweb.freebsd.org/changeset/base/355120 Log: The fdlibm hypot() implementations shouldn't potentially left-shift negative numbers (invoking undefined behavior) Summary: Various paths through hypot(x, y) will multiply x and y by a power of two, perform the calculation in a range where IEEE-754 provides greater precision, then undo the multiplication to determine the true result. Undoing that multiplication is implemented as t1*w, where t1=2**k. 2**k is often computed by taking the high word of 1.0, then adding k<<20 (for doubles or long doubles) or k<<23 (for floats) to it, then overwriting that high word. But when k is negative this left-shifts a negative value -- and that's undefined behavior in many editions of C and C++. This patch should fix all hypot implementations to compute 2**k without triggering this particular bit of undefined behavior. Test Plan: I've only very lightly tested out the hypot(double, double) change, in SpiderMonkey's JavaScript engine, for consistency with prior behavior. The other functions' changes have more or less only been eyeballed. Careful examination appreciated! Do note, however, that an error in any of these changes would most likely produce a value that is incorrect by a factor of two, so any mistake would most likely be glaring if invoked. Submitted by: Jeff Walden Obtained from: https://github.com/freebsd/freebsd/pull/414 Reviewed by: dim, lwhsu MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D22354 Modified: head/lib/msun/src/e_hypot.c head/lib/msun/src/e_hypotf.c Modified: head/lib/msun/src/e_hypot.c ============================================================================== --- head/lib/msun/src/e_hypot.c Tue Nov 26 20:46:20 2019 (r355119) +++ head/lib/msun/src/e_hypot.c Tue Nov 26 22:01:09 2019 (r355120) @@ -118,10 +118,8 @@ __ieee754_hypot(double x, double y) w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { - u_int32_t high; - t1 = 1.0; - GET_HIGH_WORD(high,t1); - SET_HIGH_WORD(t1,high+(k<<20)); + t1 = 0.0; + SET_HIGH_WORD(t1,(1023+k)<<20); return t1*w; } else return w; } Modified: head/lib/msun/src/e_hypotf.c ============================================================================== --- head/lib/msun/src/e_hypotf.c Tue Nov 26 20:46:20 2019 (r355119) +++ head/lib/msun/src/e_hypotf.c Tue Nov 26 22:01:09 2019 (r355120) @@ -77,7 +77,7 @@ __ieee754_hypotf(float x, float y) w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { - SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); + SET_FLOAT_WORD(t1,(127+k)<<23); return t1*w; } else return w; }