From patchwork Tue Feb 24 17:30:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 5264 Received: (qmail 66953 invoked by alias); 24 Feb 2015 17:35:41 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 63593 invoked by uid 89); 24 Feb 2015 17:35:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Date: Tue, 24 Feb 2015 17:30:57 +0000 From: Joseph Myers To: Subject: Fix x86/x86_64 scalb (qNaN, -Inf) (bug 16783) [committed] Message-ID: User-Agent: Alpine 2.10 (DEB 1266 2009-07-14) MIME-Version: 1.0 Various x86 / x86_64 versions of scalb / scalbf / scalbl produce spurious "invalid" exceptions for (qNaN, -Inf) arguments, because this is wrongly handled like (+/-Inf, -Inf) which *should* raise such an exception. (In fact the NaN case of the code determining whether to quietly return a zero or a NaN for second argument -Inf was accidentally dead since the code had been made to return a NaN with exception.) This patch fixes the code to do the proper test for an infinity as distinct from a NaN. (Since the existing code does nothing to distinguish qNaNs and sNaNs here, this patch doesn't either. If in future we systematically implement proper sNaN semantics following TS 18661-1:2014, there will be lots of bugs to address - Thomas found lots of issues with his patch to add SNaN tests (which never went in and would now require significant reworking).) Tested for x86_64 and x86. Committed. 2015-02-24 Joseph Myers [BZ #16783] * sysdeps/i386/fpu/e_scalb.S (__ieee754_scalb): Do not handle arguments (NaN, -Inf) the same as (+/-Inf, -Inf). * sysdeps/i386/fpu/e_scalbf.S (__ieee754_scalbf): Likewise. * sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Likewise. * sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise. * math/libm-test.inc (scalb_test_data): Add more tests. diff --git a/math/libm-test.inc b/math/libm-test.inc index ffdc153..b3396b6 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -9139,6 +9139,8 @@ static const struct test_ff_f_data scalb_test_data[] = TEST_ff_f (scalb, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, max_value, max_value, plus_oflow, OVERFLOW_EXCEPTION|ERRNO_PLUS_OFLOW), diff --git a/sysdeps/i386/fpu/e_scalb.S b/sysdeps/i386/fpu/e_scalb.S index 20d489e..6a01aa6 100644 --- a/sysdeps/i386/fpu/e_scalb.S +++ b/sysdeps/i386/fpu/e_scalb.S @@ -65,8 +65,10 @@ ENTRY(__ieee754_scalb) fstp %st fstp %st andl $0x80000000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $27, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/i386/fpu/e_scalbf.S b/sysdeps/i386/fpu/e_scalbf.S index b6dd021..12b2515 100644 --- a/sysdeps/i386/fpu/e_scalbf.S +++ b/sysdeps/i386/fpu/e_scalbf.S @@ -67,8 +67,10 @@ ENTRY(__ieee754_scalbf) fstp %st fstp %st andl $0x80000000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $27, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/i386/fpu/e_scalbl.S b/sysdeps/i386/fpu/e_scalbl.S index 83f17b2..d10b22e 100644 --- a/sysdeps/i386/fpu/e_scalbl.S +++ b/sysdeps/i386/fpu/e_scalbl.S @@ -67,8 +67,10 @@ ENTRY(__ieee754_scalbl) fstp %st fstp %st andl $0x8000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $11, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/x86_64/fpu/e_scalbl.S b/sysdeps/x86_64/fpu/e_scalbl.S index c422d53..331bee5 100644 --- a/sysdeps/x86_64/fpu/e_scalbl.S +++ b/sysdeps/x86_64/fpu/e_scalbl.S @@ -61,8 +61,10 @@ ENTRY(__ieee754_scalbl) fstp %st fstp %st andl $0x8000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $11, %edx addl %edx, %eax #ifdef PIC