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-require-effective-target inf } */
10 /* { dg-options "-fno-finite-math-only" { target sh*-*-* } } */
11 /* { dg-options "-funsafe-math-optimizations -fsigned-zeros -fno-associative-math" { target powerpc-*-darwin* powerpc*-*-linux* } } */
12
13 extern void link_error(int);
14
15 /* Return TRUE if the sign of X != sign of Y. This is important when
16 comparing signed zeros. */
17 #define CKSGN_F(X,Y) \
18 (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
19 #define CKSGN(X,Y) \
20 (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
21 #define CKSGN_L(X,Y) \
22 (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
23
24 /* We use these macros if we can only check these when optimizing. In
25 some cases we rely on other optimizations to propagate the value
26 and fold away certain constructs. Likewise for the sign testing.
27 TRUE means an error occurred. */
28 #ifdef __OPTIMIZE__
29 #define CKRES(X) (X)
30 #define CKIPTR(X,Y) X != Y
31 #define CKSGN_IPTR_F(X,Y) CKSGN_F(X,Y)
32 #define CKSGN_IPTR(X,Y) CKSGN(X,Y)
33 #define CKSGN_IPTR_L(X,Y) CKSGN_L(X,Y)
34 #else
35 #define CKRES(X) 0
36 #define CKIPTR(X,Y) 0
37 #define CKSGN_IPTR_F(X,Y) 0
38 #define CKSGN_IPTR(X,Y) 0
39 #define CKSGN_IPTR_L(X,Y) 0
40 #endif
41
42 /* Test that modf(ARG1,&iptr) == FRACRES && iptr == INTRES. Check the
43 sign in case we get -0.0. */
44 #define TESTIT_MODF(ARG,INTRES,FRACRES) do { \
45 float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \
46 if (__builtin_modff(ARG##f,&iptrf) != FRACRES##f \
47 || CKIPTR(iptrf,INTRES##f) \
48 || CKSGN_F(__builtin_modff(ARG##f,&iptrf),FRACRES##f) \
49 || CKSGN_IPTR_F(iptrf,INTRES##f)) \
50 link_error(__LINE__); \
51 if (__builtin_modf(ARG,&iptr) != FRACRES \
52 || CKIPTR(iptr,INTRES) \
53 || CKSGN(__builtin_modf(ARG,&iptr),FRACRES) \
54 || CKSGN_IPTR(iptr,INTRES)) \
55 link_error(__LINE__); \
56 if (__builtin_modfl(ARG##l,&iptrl) != FRACRES##l \
57 || CKIPTR(iptrl,INTRES##l) \
58 || CKSGN_L(__builtin_modfl(ARG##l,&iptrl),FRACRES##l) \
59 || CKSGN_IPTR_L(iptrl,INTRES##l)) \
60 link_error(__LINE__); \
61 } while (0)
62
63 /* Test that modf(NEG FUNCARG(ARGARG, &iptr)) == FRACRES &&
64 FUNCRES(iptr) is true. Check the sign of both as well. This is
65 for checking an argument of Inf. */
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
85 /* Test that FUNCRES(modf(NEG FUNCARG(ARGARG, &iptr))) is true &&
86 FUNCRES(iptr) is true. Check the sign of both as well. This is
87 for checking an argument of NaN. */
88 #define TESTIT_MODF3(NEG,FUNCARG,ARGARG,FUNCRES) do { \
89 float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \
90 if (CKRES(!__builtin_##FUNCRES##f(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf))) \
91 || CKSGN_F(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf), NEG 1) \
92 || CKIPTR(!__builtin_##FUNCRES##f(iptrf),0) \
93 || CKSGN_IPTR_F(iptrf,NEG 1)) \
94 link_error(__LINE__); \
95 if (CKRES(!__builtin_##FUNCRES(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr))) \
96 || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), NEG 1) \
97 || CKIPTR(!__builtin_##FUNCRES(iptr),0) \
98 || CKSGN_IPTR(iptr,NEG 1)) \
99 link_error(__LINE__); \
100 if (CKRES(!__builtin_##FUNCRES##l(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl))) \
101 || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), NEG 1) \
102 || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \
103 || CKSGN_IPTR_L(iptrl,NEG 1)) \
104 link_error(__LINE__); \
105 } while (0)
106
107 void __attribute__ ((__noinline__))
foo(void)108 foo(void)
109 {
110 /* Test that modf(ARG1,&iptr) -> ARG3 && iptr == ARG2. */
111 TESTIT_MODF (0x1p10F+0.5, 0x1p10, 0.5);
112 TESTIT_MODF (0x1p10F+0x1p-10, 0x1p10, 0x1p-10);
113 TESTIT_MODF (12345678L/17.0, 726216.0, -726216L+12345678L/17.0);
114 TESTIT_MODF (555.555, 555.0, -555+555.555);
115 TESTIT_MODF (5000/11.0, 454.0, -454+5000/11.0);
116 TESTIT_MODF (1000/7.0, 142.0, -142+1000/7.0);
117 TESTIT_MODF (123/7.0, 17.0, -17+123/7.0);
118 TESTIT_MODF (117/7.0, 16.0, -16+117/7.0);
119 TESTIT_MODF (5.5, 5.0, 0.5);
120 TESTIT_MODF (1.5, 1.0, 0.5);
121 TESTIT_MODF (4/3.0, 1.0, -1+4/3.0);
122 TESTIT_MODF (1.0, 1.0, 0.0);
123 TESTIT_MODF (0.5, 0.0, 0.5);
124 TESTIT_MODF (4/9.0, 0.0, 4/9.0);
125 TESTIT_MODF (1/3.0, 0.0, 1/3.0);
126 TESTIT_MODF (1/9.0, 0.0, 1/9.0);
127 TESTIT_MODF (0.0, 0.0, 0.0);
128
129 TESTIT_MODF (-0.0, -0.0, -0.0);
130 TESTIT_MODF (-1/9.0, -0.0, -1/9.0);
131 TESTIT_MODF (-1/3.0, -0.0, -1/3.0);
132 TESTIT_MODF (-4/9.0, -0.0, -4/9.0);
133 TESTIT_MODF (-0.5, -0.0, -0.5);
134 TESTIT_MODF (-1.0, -1.0, -0.0);
135 TESTIT_MODF (-4/3.0, -1.0, 1-4/3.0);
136 TESTIT_MODF (-1.5, -1.0, -0.5);
137 TESTIT_MODF (-5.5, -5.0, -0.5);
138 TESTIT_MODF (-117/7.0, -16.0, 16-117/7.0);
139 TESTIT_MODF (-123/7.0, -17.0, 17-123/7.0);
140 TESTIT_MODF (-1000/7.0, -142.0, 142-1000/7.0);
141 TESTIT_MODF (-5000/11.0, -454.0, 454-5000/11.0);
142 TESTIT_MODF (-555.555, -555.0, 555-555.555);
143 TESTIT_MODF (-12345678L/17.0, -726216.0, 726216L-12345678L/17.0);
144 TESTIT_MODF (-0x1p10F-0x1p-10, -0x1p10, -0x1p-10);
145 TESTIT_MODF (-0x1p10F-0.5, -0x1p10, -0.5);
146
147
148 /* Test for modf(+-Inf,&i) -> (i=+-0.0, +-Inf). */
149 TESTIT_MODF2 ( ,inf, , isinf, 0.0);
150 TESTIT_MODF2 (- ,inf, , isinf, -0.0);
151
152 /* Test for and modf(+-NaN,&i) -> (i=+-NaN, +-NaN). */
153 TESTIT_MODF3 ( ,nan, "", isnan);
154 TESTIT_MODF3 (- ,nan, "", isnan);
155 }
156
main()157 int main()
158 {
159 foo();
160
161 return 0;
162 }
163