2009-07-17 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / gcc.dg / torture / builtin-modf-1.c
blob05e16ac2cc473bd98395653a69be8575a051b1af
1 /* Copyright (C) 2007 Free Software Foundation.
3 Verify that built-in folding of modf is correctly performed by the
4 compiler.
6 Origin: Kaveh R. Ghazi, February 23, 2007. */
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* } } */
12 extern void link_error(int);
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)))
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
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)
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
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
140 void __attribute__ ((__noinline__))
141 foo(void)
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);
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);
181 /* Test for modf(+-Inf,&i) -> (i=+-0.0, +-Inf). */
182 TESTIT_MODF2 ( ,inf, , isinf, 0.0);
183 TESTIT_MODF2 (- ,inf, , isinf, -0.0);
185 /* Test for and modf(+-NaN,&i) -> (i=+-NaN, +-NaN). */
186 TESTIT_MODF3 ( ,nan, "", isnan);
187 TESTIT_MODF3 (- ,nan, "", isnan);
190 int main()
192 foo();
194 return 0;