1 /* Copyright (C) 2006  Free Software Foundation.
2 
3    Verify that built-in math function folding of fmin/fmax is
4    correctly performed by the compiler.
5 
6    Origin: Kaveh R. Ghazi,  November 13, 2006.  */
7 
8 /* { dg-do link } */
9 /* { dg-options "-fno-math-errno" } */
10 /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
11 
12 /* All references to link_error should go away at compile-time.  */
13 extern void link_error(int);
14 
15 #define DECLARE(FUNC) \
16   extern float FUNC##f (float); \
17   extern double FUNC (double); \
18   extern long double FUNC##l (long double)
19 #define DECLARE2(FUNC) \
20   extern float FUNC##f (float, float); \
21   extern double FUNC (double, double); \
22   extern long double FUNC##l (long double, long double)
23 
24 DECLARE2(fmin);
25 DECLARE2(fmax);
26 DECLARE(fabs);
27 extern int pure(int) __attribute__ ((__pure__));
28 
29 /* Test that FUNC(x,x) == x.  We cast to (long) so "!=" folds.  */
30 #define TEST_EQ(FUNC) do { \
31   if ((long)FUNC##f(xf,xf) != (long)xf) \
32     link_error(__LINE__); \
33   if ((long)FUNC(x,x) != (long)x) \
34     link_error(__LINE__); \
35   if ((long)FUNC##l(xl,xl) != (long)xl) \
36     link_error(__LINE__); \
37   } while (0)
38 
39 /* Test that FUNC(purefn,purefn) == purefn.  We cast to (long) so "!=" folds.  */
40 #define TEST_EQ_PURE(FUNC) do { \
41   if ((long)FUNC##f(pure(i),pure(i)) != (long)FUNC##f(pure(i),pure(i))) \
42     link_error(__LINE__); \
43   if ((long)FUNC(pure(i),pure(i)) != (long)FUNC(pure(i),pure(i))) \
44     link_error(__LINE__); \
45   if ((long)FUNC##l(pure(i),pure(i)) != (long)FUNC##l(pure(i),pure(i))) \
46     link_error(__LINE__); \
47   } while (0)
48 
49 /* Test that FIXFUNC(FUNC(int1,int2)) == (TYPE)FUNC(int1,int2),
50    i.e. FIXFUNC should be folded away and replaced with a cast.  */
51 #define TEST_FIXFUNC(FUNC,FIXFUNC,TYPE) do { \
52   if (FIXFUNC##f(FUNC##f(i,j)) != (TYPE)FUNC##f(i,j)) \
53     link_error(__LINE__); \
54   if (FIXFUNC(FUNC(i,j)) != (TYPE)FUNC(i,j)) \
55     link_error(__LINE__); \
56   if (FIXFUNC##l(FUNC##l(i,j)) != (TYPE)FUNC##l(i,j)) \
57     link_error(__LINE__); \
58   } while (0)
59 
60 /* Test that FUNC(int1,int2) has an integer return type.  */
61 #define TEST_INT(FUNC) do { \
62   TEST_FIXFUNC(FUNC,__builtin_lround,long); \
63   TEST_FIXFUNC(FUNC,__builtin_llround,long long); \
64   TEST_FIXFUNC(FUNC,__builtin_lrint,long); \
65   TEST_FIXFUNC(FUNC,__builtin_llrint,long long); \
66   TEST_FIXFUNC(FUNC,__builtin_lceil,long); \
67   TEST_FIXFUNC(FUNC,__builtin_llceil,long long); \
68   TEST_FIXFUNC(FUNC,__builtin_lfloor,long); \
69   TEST_FIXFUNC(FUNC,__builtin_llfloor,long long); \
70   } while (0)
71 
72 /* Test that (long)fabs(FUNC(fabs(x),fabs(y))) ==
73    (long)FUNC(fabs(x),fabs(y)).  We cast to (long) so "!=" folds.  */
74 #define TEST_NONNEG(FUNC) do { \
75   if ((long)fabsf(FUNC##f(fabsf(xf),fabsf(yf))) != (long)FUNC##f(fabsf(xf),fabsf(yf))) \
76     link_error(__LINE__); \
77   if ((long)fabs(FUNC(fabs(x),fabs(y))) != (long)FUNC(fabs(x),fabs(y))) \
78     link_error(__LINE__); \
79   if ((long)fabsl(FUNC##l(fabsl(xl),fabsl(yl))) != (long)FUNC##l(fabsl(xl),fabsl(yl))) \
80     link_error(__LINE__); \
81   } while (0)
82 
83 /* Test that FUNC(NaN,x) == x.  We cast to (long) so "!=" folds.  Set
84    parameter SIGNAL to `s' for testing signaling NaN.  */
85 #define TEST_NAN(FUNC,SIGNAL) do { \
86   if ((long)FUNC##f(__builtin_nan##SIGNAL##f(""),xf) != (long)xf) \
87     link_error(__LINE__); \
88   if ((long)FUNC##f(xf,__builtin_nan##SIGNAL##f("")) != (long)xf) \
89     link_error(__LINE__); \
90   if ((long)FUNC(__builtin_nan##SIGNAL(""),x) != (long)x) \
91     link_error(__LINE__); \
92   if ((long)FUNC(x,__builtin_nan##SIGNAL("")) != (long)x) \
93     link_error(__LINE__); \
94   if ((long)FUNC##l(__builtin_nan##SIGNAL##l(""),xl) != (long)xl) \
95     link_error(__LINE__); \
96   if ((long)FUNC##l(xl,__builtin_nan##SIGNAL##l("")) != (long)xl) \
97     link_error(__LINE__); \
98   } while (0)
99 
100 void __attribute__ ((__noinline__))
foo(float xf,double x,long double xl,float yf,double y,long double yl,int i,int j)101      foo (float xf, double x, long double xl,
102 	  float yf, double y, long double yl,
103 	  int i, int j)
104 {
105   TEST_EQ(fmin);
106   TEST_EQ(fmax);
107 
108 #ifdef __OPTIMIZE__
109   TEST_EQ_PURE(fmin);
110   TEST_EQ_PURE(fmax);
111 #endif
112 
113   TEST_INT(fmin);
114   TEST_INT(fmax);
115 
116   TEST_NONNEG(fmin);
117   TEST_NONNEG(fmax);
118 
119   TEST_NAN(fmin,);
120   TEST_NAN(fmax,);
121   TEST_NAN(fmin,s);
122   TEST_NAN(fmax,s);
123 }
124 
main()125 int main()
126 {
127   foo (1,1,1,1,1,1,1,1);
128   return 0;
129 }
130