1: /* Beginning of modification history */
   2: /* Written 02-04-10 by Paul Green (Paul.Green@stratus.com) */
   3: /* End of modification history */
   4: 
   5: /* This test case is extracted from Perl version 5.7.3.  It is
   6:    in the Perl_unpack_str function of the pp_pack.c source file.
   7: 
   8:    GCC 2.95.2 improperly assumes that it can compensate for an
   9:    extra fsub by performing a fadd.  This would work in
  10:    fixed-point arithmetic, but does not work in floating-point
  11:    arithmetic.
  12: 
  13:    This problem has been seen on HP-UX and on Stratus VOS, both
  14:    of which have an HP PA-RISC target (hppa1.1).  The Stratus
  15:    bug number is gnu_g++-220.  */
  16: 
  17: /* #define _POSIX_C_SOURCE 199506L -- added by Configure */
  18: #include <stdio.h>
  19: #include <string.h>
  20: #include <math.h>
  21: 
  22: void test(double *result)
  23: {
  24:     float   afloat;
  25:     double  adouble;
  26:     int     checksum = 0;
  27:     unsigned    cuv = 0;
  28:     double  cdouble = 0.0;
  29:     const int   bits_in_uv = 8 * sizeof(cuv);
  30: 
  31:     checksum = 53;
  32:     cdouble = -1.0;
  33: 
  34:     if (checksum) {
  35:         if (checksum > bits_in_uv) {
  36:             double trouble;
  37: 
  38:             adouble = (double) (1 << (checksum & 15));
  39: 
  40:             while (checksum >= 16) {
  41:                 checksum -= 16;
  42:                 adouble *= 65536.0;
  43:             }
  44: 
  45:             /* At -O1, GCC 2.95.2 compiles the following loop
  46: 			   into:
  47: 
  48: 			   L$0014
  49: 				fcmp,dbl,>= %fr4,%fr0
  50: 				ftest
  51: 				b L$0014
  52: 				fadd,dbl %fr4,%fr12,%fr4
  53: 				fsub,dbl %fr4,%fr12,%fr4
  54: 
  55: 				This code depends on the floading-add and
  56: 				floating-subtract retaining all of the
  57: 				precision present in the operands.  There is
  58: 				no such guarantee when using floating-point,
  59: 				as this test case demonstrates.
  60: 
  61: 				The code is okay at -O0.  */
  62: 
  63:             while (cdouble < 0.0)
  64:                 cdouble += adouble;
  65: 
  66:             cdouble = modf (cdouble / adouble, &trouble) * adouble;
  67:         }
  68:     }
  69: 
  70:     *result = cdouble;
  71: }
  72: 
  73: int main (int argc, char ** argv)
  74: {
  75: double  value;
  76: 
  77:     test (&value);
  78: 
  79:     if (argc == 2 && !strcmp(argv[1],"-v"))
  80:         printf ("value = %.18e\n", value);
  81: 
  82:     if (value != 9.007199254740991e+15) {
  83:         printf ("t001 fails!\n");
  84:         return -1;
  85:     }
  86:     else {
  87:         printf ("t001 works.\n");
  88:         return 0;
  89:     }
  90: }

Defined functions

main defined in line 73; never used
test defined in line 22; used 1 times
  • in line 77
Last modified: 2002-12-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2560
Valid CSS Valid XHTML 1.0 Strict