Bug 13563 - LoP asinl returns unexpected value on long double
Summary: LoP asinl returns unexpected value on long double
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: math (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Steven Munroe
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-05 06:56 UTC by Jeff Guo
Modified: 2014-06-27 11:15 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
patch with updates to e_asinl.c and libm-test.inc (816 bytes, patch)
2012-02-16 17:13 UTC, Dave Flaherty
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Guo 2012-01-05 06:56:05 UTC
#include <stdio.h>
#include <float.h>
#include <math.h>

typedef union { long double ld; struct{long l1, l2, l3, l4;} s; } U ;

int main(void) {
   U u ;
   long double arg = (1.L-((__extension__ 0x1p-105L))/(long double)2);
   long double a = asinl(arg);

   u.ld = arg ;
   printf("size of long double=%d long=%d\n", sizeof(long double), sizeof(long));
   printf("%X %X %X %X\n", u.s.l1,u.s.l2,u.s.l3,u.s.l4);
   printf("%.30Lg\n",arg);
   printf("%.30Lg\n",a);

 return 0;
}

> gcc t.c -lm;./a.out

EXPECTED OUTPUT:

size of long double=8 long=4
3FF00000 0 FE97FF4 0
1
1.57079632679489655799898173427


ACTUAL OUTPUT:
size of long double=16 long=4
3FF00000 0 B9500000 0
1
nan   <-should be 1.570796326794....

This issue happens at Linux on Power system
Comment 1 Steven Munroe 2012-01-05 14:44:59 UTC
I did not see any info on which distro and release?

But it looks like this is fixed up stream, And the fix is available via the advance toolchain: http://ausgsa.ibm.com/projects/p/ppctoolchain/web/public/at/at5.0/suse/SLES_10/

sjmunroe@spokane1:~/src> export PATH=/opt/at5.0/bin:$PATH
sjmunroe@spokane1:~/src> gcc -O2 -g bugz-13563.c -lm -o bugz-13563
sjmunroe@spokane1:~/src> ./bugz-13563
size of long double=16 long=8
0 0 0 37DF8
1
1.57079632679489646222207582326
Comment 2 Steven Munroe 2012-01-05 19:19:01 UTC
Oops false resolve, seems the GCC-4.6 compiler will optimize the asinl call away and load the correct const result for -O1 or higher. I see the same failure when compiled at -O0.

The team will take a closer look.
Comment 3 Dave Flaherty 2012-01-24 21:02:41 UTC
It appears there are a couple issues with this code.  The first issue is how the code is checking for values greater than 1 (or less than -1), and the other issue is how the code gets the absolute value of the input argument. 

Patch and test suite update will be provided shortly.
Comment 4 Dave Flaherty 2012-02-16 17:13:29 UTC
Created attachment 6223 [details]
patch with updates to e_asinl.c and libm-test.inc

* sysdeps/ieee754/ldbl-128ibm/e_asinl.c (__ieee754_asinl): Updated the |x|  
  code and specifically check for |x|>1.
* math/libm-test.inc (asin_test): Added a long double and  
  LDBL_MANT_DIG == 106 test for values near |1|.
Comment 5 Joseph Myers 2012-03-02 00:58:24 UTC
The patch should be posted to libc-alpha for review.

You shouldn't be updating copyright dates in a copyright notice in the name of Sun, only those in FSF copyright notices....
Comment 6 Adhemerval Zanella Netto 2012-05-06 14:43:27 UTC
Commit '31dc8730af585d8e13021484752fb20decae0661' fixes this and also the same issue for acosl. My patch corrects the case for value near '1' that depends on both double and also for every comparison using the wrong absolute value for 'x'.
Comment 7 Adhemerval Zanella Netto 2012-05-06 14:44:30 UTC
Fixed by commit '31dc8730af585d8e13021484752fb20decae0661'.