IV36069: Exception bit folded incorrectly with -qfloat=fenv -O2

Subscribe

You can track all active APARs for this component.

APAR status

  • Closed as program error.

Error description

  • With options -qfloat=fenv -O2, the exception bit is folded
    incorrectly sometimes, which may cause libraries or programs to
    mal-behave.
    The following test case outputs bits 32:55 of the FPSCR in
    binary before and after the test expression is executed.
    It tests 4 idioms:  1/0, 0/0, inf-inf, (inf+x)-inf.  The
    exception bit is bit 32 (the left most bit).  It should be 0
    before and 1 after the exception call.
    For C, the FPSCR is being set correctly for all but the inf-inf
    case.  This is the expected result.
    $ cat testmain.c
    #include <math.h>
    void printb (int val) {
      int j;
      printf ("fpscr=");
      for (int j = 31; j >= 0; j --) {
        if (val & 0x80000000) printf("1");
        else printf("0");
        if (j%4==0) printf(" ");
        val<<=1;
      }
      printf ("\n");
    }
    void printd (long double val) {
      printf ("retval=%e\n", val);
    }
    main(){
      int i;
      double x, y;
      union {double d; int i[2];} u;
      extern double test_inf(double), test_nan1(double),
    test_nan2(double),
        test_nan3(double);
      x = 1.0;
      for (i=0; i<4; i++) {
        u.d = __readflm();
        u.i[1] &= ~0xFFFFFF00;  // clear exception bits
        u.d = __setflm (u.d);
    
        u.d = __readflm();
        printb (u.i[1]);
    
        switch (i) {
          case 0:
            y = test_inf(x);
            break;
          case 1:
            y = test_nan1(x);
            break;
          case 3:
            y = test_nan2(x);
            break;
          case 4:
            y = test_nan3(x);
            break;
        }
    
        u.d = __readflm();
        printb (u.i[1]);
    
        printd (y);
      }
    }
    $ cat testfuncs.c
    double test_inf(double x) {
      return 1.0/0.0;
    }
    double test_nan1(double x) {
      return 0.0/0.0;
    }
    double test_nan2(double x) {
      double inf = 1.0/0.0;
      return inf - inf;
    }
    double test_nan3(double x) {
      double inf = 1.0/0.0;
      return (inf+x) - inf;
    }
    Actual Output:
    + xlc -O2 -qfloat=fenv -c testmain.c -qfloat=fenv
    + xlc -O2 -qfloat=fenv testfuncs.c testmain.o
    "testfuncs.c", line 2.14: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 6.14: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 10.20: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 15.20: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    + ./a.out
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    retval=INF
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    retval=NaNQ
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    retval=NaNQ
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    retval=NaNQ
    Expected Output:
    + xlc -O2 -qfloat=fenv -c testmain.c -qfloat=fenv
    + xlc -O2 -qfloat=fenv testfuncs.c testmain.o
    "testfuncs.c", line 2.14: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 6.14: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 10.20: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    "testfuncs.c", line 15.20: 1506-232 (I) Divisor for modulus or
    division operator cannot be zero.
    + ./a.out
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=1000 0100 0000 0000 0101 0000 0000 0000
    retval=INF
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=1010 0000 0010 0001 0001 0000 0000 0000
    retval=NaNQ
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    retval=NaNQ
    fpscr=0000 0000 0000 0000 0000 0000 0000 0000
    fpscr=1010 0100 1000 0001 0001 0000 0000 0000
    retval=NaNQ
    

Local fix

  • Use -qfloat=nofold
    

Problem summary

  • PROBLEM DESCRIPTION: Expressions that may set FPSCR bits may be
    folded away under -qfloat=fenv
    
    USERS AFFECTED: Those who require the value of the FPSCR to be
    faithfully updated upon evaluation of floating-point
    expressions at -O2 and up.
    

Problem conclusion

  • Fixed compile-time floating point folding to respect
    -qfloat=fenv at -O2 and up, and preserve expressions that would
    modify the FPSCR. Apply provided service.
    

Temporary fix

Comments

APAR Information

  • APAR number

    IV36069

  • Reported component name

    XL C/C++ AIX

  • Reported component ID

    5724X1300

  • Reported release

    B10

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt

  • Submitted date

    2013-01-29

  • Closed date

    2013-08-13

  • Last modified date

    2013-08-13

  • APAR is sysrouted FROM one or more of the following:

  • APAR is sysrouted TO one or more of the following:

    IV49627 LI77652

Fix information

  • Fixed component name

    XL C FOR AIX

  • Fixed component ID

    5724X1200

Applicable component levels

  • RB10 PSY U860969

       UP C



Rate this page:

(0 users)Average rating

Document information


More support for:

XL C for AIX

Software version:

11.1

Reference #:

IV36069

Modified date:

2013-08-13

Translate my page

Machine Translation

Content navigation