OSDN Git Service

Revert delta 190174
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / torture / builtin-modf-1.c
1 /* Copyright (C) 2007  Free Software Foundation.
2
3    Verify that built-in folding of modf is correctly performed by the
4    compiler.
5
6    Origin: Kaveh R. Ghazi,  February 23, 2007.  */
7
8 /* { dg-do link } */
9 /* { dg-options "-fno-finite-math-only" { target sh*-*-* } } */
10 /* { dg-options "-funsafe-math-optimizations -fsigned-zeros -fno-associative-math" { target powerpc-*-darwin* powerpc*-*-linux* } } */
11
12 extern void link_error(int);
13
14 /* Return TRUE if the sign of X != sign of Y.  This is important when
15    comparing signed zeros.  */
16 #define CKSGN_F(X,Y) \
17   (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
18 #define CKSGN(X,Y) \
19   (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
20 #define CKSGN_L(X,Y) \
21   (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
22
23 /* We use these macros if we can only check these when optimizing.  In
24    some cases we rely on other optimizations to propagate the value
25    and fold away certain constructs.  Likewise for the sign testing.
26    TRUE means an error occurred.  */
27 #ifdef __OPTIMIZE__
28 #define CKRES(X) (X)
29 #define CKIPTR(X,Y) X != Y
30 #define CKSGN_IPTR_F(X,Y) CKSGN_F(X,Y)
31 #define CKSGN_IPTR(X,Y) CKSGN(X,Y)
32 #define CKSGN_IPTR_L(X,Y) CKSGN_L(X,Y)
33 #else
34 #define CKRES(X) 0
35 #define CKIPTR(X,Y) 0
36 #define CKSGN_IPTR_F(X,Y) 0
37 #define CKSGN_IPTR(X,Y) 0
38 #define CKSGN_IPTR_L(X,Y) 0
39 #endif
40
41 /* Test that modf(ARG1,&iptr) == FRACRES && iptr == INTRES.  Check the
42    sign in case we get -0.0.  */
43 #define TESTIT_MODF(ARG,INTRES,FRACRES) do { \
44   float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \
45   if (__builtin_modff(ARG##f,&iptrf) != FRACRES##f \
46       || CKIPTR(iptrf,INTRES##f) \
47       || CKSGN_F(__builtin_modff(ARG##f,&iptrf),FRACRES##f) \
48       || CKSGN_IPTR_F(iptrf,INTRES##f)) \
49     link_error(__LINE__); \
50   if (__builtin_modf(ARG,&iptr) != FRACRES \
51       || CKIPTR(iptr,INTRES) \
52       || CKSGN(__builtin_modf(ARG,&iptr),FRACRES) \
53       || CKSGN_IPTR(iptr,INTRES)) \
54     link_error(__LINE__); \
55   if (__builtin_modfl(ARG##l,&iptrl) != FRACRES##l \
56       || CKIPTR(iptrl,INTRES##l) \
57       || CKSGN_L(__builtin_modfl(ARG##l,&iptrl),FRACRES##l) \
58       || CKSGN_IPTR_L(iptrl,INTRES##l)) \
59     link_error(__LINE__); \
60   } while (0)
61
62 /* Test that modf(NEG FUNCARG(ARGARG, &iptr)) == FRACRES &&
63    FUNCRES(iptr) is true.  Check the sign of both as well.  This is
64    for checking an argument of Inf.  */
65 #ifndef __SPU__
66 #define TESTIT_MODF2(NEG,FUNCARG,ARGARG,FUNCRES,FRACRES) do { \
67   float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \
68   if (__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf) != FRACRES##f \
69       || CKSGN_F(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf), FRACRES##f) \
70       || CKIPTR(!__builtin_##FUNCRES##f(iptrf),0) \
71       || CKSGN_IPTR_F(iptrf,FRACRES##f)) \
72     link_error(__LINE__); \
73   if (__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr) != FRACRES \
74       || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), FRACRES) \
75       || CKIPTR(!__builtin_##FUNCRES(iptr),0) \
76       || CKSGN_IPTR(iptr,FRACRES)) \
77     link_error(__LINE__); \
78   if (__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl) != FRACRES##l \
79       || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), FRACRES##l) \
80       || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \
81       || CKSGN_IPTR_L(iptrl,FRACRES##l)) \
82     link_error(__LINE__); \
83   } while (0)
84 #else
85 #define TESTIT_MODF2(NEG,FUNCARG,ARGARG,FUNCRES,FRACRES) do { \
86   /* SPU single-precision floating point format does not support Inf or Nan.  */ \
87   double iptr = 0.5; long double iptrl = 0.5; \
88   if (__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr) != FRACRES \
89       || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), FRACRES) \
90       || CKIPTR(!__builtin_##FUNCRES(iptr),0) \
91       || CKSGN_IPTR(iptr,FRACRES)) \
92     link_error(__LINE__); \
93   if (__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl) != FRACRES##l \
94       || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), FRACRES##l) \
95       || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \
96       || CKSGN_IPTR_L(iptrl,FRACRES##l)) \
97     link_error(__LINE__); \
98   } while (0)
99 #endif
100
101 /* Test that FUNCRES(modf(NEG FUNCARG(ARGARG, &iptr))) is true &&
102    FUNCRES(iptr) is true.  Check the sign of both as well.  This is
103    for checking an argument of NaN.  */
104 #ifndef __SPU__
105 #define TESTIT_MODF3(NEG,FUNCARG,ARGARG,FUNCRES) do { \
106   float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \
107   if (CKRES(!__builtin_##FUNCRES##f(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf))) \
108       || CKSGN_F(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf), NEG 1) \
109       || CKIPTR(!__builtin_##FUNCRES##f(iptrf),0) \
110       || CKSGN_IPTR_F(iptrf,NEG 1)) \
111     link_error(__LINE__); \
112   if (CKRES(!__builtin_##FUNCRES(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr))) \
113       || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), NEG 1) \
114       || CKIPTR(!__builtin_##FUNCRES(iptr),0) \
115       || CKSGN_IPTR(iptr,NEG 1)) \
116     link_error(__LINE__); \
117   if (CKRES(!__builtin_##FUNCRES##l(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl))) \
118       || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), NEG 1) \
119       || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \
120       || CKSGN_IPTR_L(iptrl,NEG 1)) \
121     link_error(__LINE__); \
122   } while (0)
123 #else
124 #define TESTIT_MODF3(NEG,FUNCARG,ARGARG,FUNCRES) do { \
125   /* SPU single-precision floating point format does not support Inf or Nan.  */ \
126   double iptr = 0.5; long double iptrl = 0.5; \
127   if (CKRES(!__builtin_##FUNCRES(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr))) \
128       || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), NEG 1) \
129       || CKIPTR(!__builtin_##FUNCRES(iptr),0) \
130       || CKSGN_IPTR(iptr,NEG 1)) \
131     link_error(__LINE__); \
132   if (CKRES(!__builtin_##FUNCRES##l(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl))) \
133       || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), NEG 1) \
134       || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \
135       || CKSGN_IPTR_L(iptrl,NEG 1)) \
136     link_error(__LINE__); \
137   } while (0)
138 #endif
139
140 void __attribute__ ((__noinline__))
141 foo(void)
142 {
143   /* Test that modf(ARG1,&iptr) -> ARG3 && iptr == ARG2.  */
144   TESTIT_MODF (0x1p10F+0.5, 0x1p10, 0.5);
145   TESTIT_MODF (0x1p10F+0x1p-10, 0x1p10, 0x1p-10);
146   TESTIT_MODF (12345678L/17.0, 726216.0, -726216L+12345678L/17.0);
147   TESTIT_MODF (555.555, 555.0, -555+555.555);
148   TESTIT_MODF (5000/11.0, 454.0, -454+5000/11.0);
149   TESTIT_MODF (1000/7.0, 142.0, -142+1000/7.0);
150   TESTIT_MODF (123/7.0, 17.0, -17+123/7.0);
151   TESTIT_MODF (117/7.0, 16.0, -16+117/7.0);
152   TESTIT_MODF (5.5, 5.0, 0.5);
153   TESTIT_MODF (1.5, 1.0, 0.5);
154   TESTIT_MODF (4/3.0, 1.0, -1+4/3.0);
155   TESTIT_MODF (1.0, 1.0, 0.0);
156   TESTIT_MODF (0.5, 0.0, 0.5);
157   TESTIT_MODF (4/9.0, 0.0, 4/9.0);
158   TESTIT_MODF (1/3.0, 0.0, 1/3.0);
159   TESTIT_MODF (1/9.0, 0.0, 1/9.0);
160   TESTIT_MODF (0.0, 0.0, 0.0);
161
162   TESTIT_MODF (-0.0, -0.0, -0.0);
163   TESTIT_MODF (-1/9.0, -0.0, -1/9.0);
164   TESTIT_MODF (-1/3.0, -0.0, -1/3.0);
165   TESTIT_MODF (-4/9.0, -0.0, -4/9.0);
166   TESTIT_MODF (-0.5, -0.0, -0.5);
167   TESTIT_MODF (-1.0, -1.0, -0.0);
168   TESTIT_MODF (-4/3.0, -1.0, 1-4/3.0);
169   TESTIT_MODF (-1.5, -1.0, -0.5);
170   TESTIT_MODF (-5.5, -5.0, -0.5);
171   TESTIT_MODF (-117/7.0, -16.0, 16-117/7.0);
172   TESTIT_MODF (-123/7.0, -17.0, 17-123/7.0);
173   TESTIT_MODF (-1000/7.0, -142.0, 142-1000/7.0);
174   TESTIT_MODF (-5000/11.0, -454.0, 454-5000/11.0);
175   TESTIT_MODF (-555.555, -555.0, 555-555.555);
176   TESTIT_MODF (-12345678L/17.0, -726216.0, 726216L-12345678L/17.0);
177   TESTIT_MODF (-0x1p10F-0x1p-10, -0x1p10, -0x1p-10);
178   TESTIT_MODF (-0x1p10F-0.5, -0x1p10, -0.5);
179
180   
181   /* Test for modf(+-Inf,&i) -> (i=+-0.0, +-Inf).  */
182   TESTIT_MODF2 ( ,inf, , isinf, 0.0);
183   TESTIT_MODF2 (- ,inf, , isinf, -0.0);
184
185   /* Test for and modf(+-NaN,&i) -> (i=+-NaN, +-NaN).  */
186   TESTIT_MODF3 ( ,nan, "", isnan);
187   TESTIT_MODF3 (- ,nan, "", isnan);
188 }
189
190 int main()
191 {
192   foo();
193   
194   return 0;
195 }