1 /* Test the noipa attribute. */
2 /* { dg-do compile } */
3 /* { dg-options "-O2 -fdump-tree-optimized" } */
4 /* { dg-require-effective-target alloca } */
5
6 static inline int __attribute__((noipa))
7 fn1 (void) /* { dg-warning "inline function \[^\n\]* given attribute 'noinline'" "" } */
8 {
9 return 1;
10 }
11
12 /* Verify the function is not inlined into its caller. */
13
14 static __attribute__((noipa)) int
15 fn2 (int x, int y)
16 {
17 return x + y;
18 }
19
20 int
21 fn3 (int x)
22 {
23 return fn2 (x, 0);
24 }
25
26 /* { dg-final { scan-tree-dump "= fn2 \\(" "optimized" } } */
27
28 void fn4 (char *);
29
30 /* Verify the function is not cloned. */
31
32 __attribute__((__noipa__)) static int
33 fn5 (int x, int y)
34 {
35 char *p = __builtin_alloca (x + y);
36 fn4 (p);
37 return x + y;
38 }
39
40 int
41 fn6 (int x)
42 {
43 return fn5 (x, 2);
44 }
45
46 /* { dg-final { scan-tree-dump "= fn5 \\(" "optimized" } } */
47 /* { dg-final { scan-tree-dump-not "fn5\\.constprop" "optimized" } } */
48
49 /* Verify we still remove unused function calls, even if they have
50 noipa attribute. */
51
52 static void fn7 (void) __attribute__((noipa));
53 static void
54 fn7 (void)
55 {
56 }
57
58 /* { dg-final { scan-tree-dump-not "fn7 \\(" "optimized" } } */
59
60 /* Verify noipa functions are not ICF optimized. */
61
62 static __attribute__((noipa)) int
63 fn8 (int x)
64 {
65 return x + 12;
66 }
67
68 static __attribute__((noipa)) int
69 fn9 (int x)
70 {
71 return x + 12;
72 }
73
74 int
75 fn10 (int x)
76 {
77 return fn8 (x) + fn9 (x);
78 }
79
80 /* { dg-final { scan-tree-dump "fn8 \\(int" "optimized" } } */
81 /* { dg-final { scan-tree-dump "fn9 \\(int" "optimized" } } */
82
83 /* Verify IPA-VRP is not performed. */
84
85 void fn11 (void);
86
87 static int __attribute__((noipa))
88 fn12 (int x)
89 {
90 if (x < 6 || x >= 29)
91 fn11 ();
92 }
93
94 void
95 fn13 (int x)
96 {
97 fn12 (6 + (x & 15));
98 }
99
100 /* { dg-final { scan-tree-dump "fn11 \\(\\)" "optimized" } } */
101
102 void fn14 (void);
103
104 __attribute__((noipa)) static int
105 fn15 (int x)
106 {
107 return x & 7;
108 }
109
110 int
111 fn16 (int x)
112 {
113 x = fn15 (x);
114 if (x < 0 || x >= 7)
115 fn14 ();
116 }
117
118 /* { dg-final { scan-tree-dump "fn14 \\(\\)" "optimized" } } */
119
120 /* Verify IPA BIT CP is not performed. */
121
122 void fn17 (void);
123
124 __attribute__((noipa)) static int
125 fn18 (int x)
126 {
127 if (x & 8)
128 fn17 ();
129 }
130
131 void
132 fn19 (void)
133 {
134 fn18 (1);
135 fn18 (2);
136 fn18 (4);
137 fn18 (16);
138 fn18 (32);
139 fn18 (64);
140 }
141
142 /* { dg-final { scan-tree-dump "fn17 \\(\\)" "optimized" } } */
143
144 /* Ensure pure/const discovery is not performed. */
145
146 int var1;
147 void fn20 (void);
148
149 __attribute__((noipa)) static int
150 fn21 (int x, int y)
151 {
152 return x * y;
153 }
154
155 int
156 fn22 (void)
157 {
158 var1 = 7;
159 asm volatile ("" : "+g" (var1) : : "memory");
160 int a = var1;
161 int b = fn21 (a, a);
162 if (a != var1)
163 fn20 ();
164 return b;
165 }
166
167 /* { dg-final { scan-tree-dump "fn20 \\(\\)" "optimized" } } */
168
169 /* Verify IPA alignment propagation is not performed. */
170
171 static __attribute__ ((aligned(16))) char var2[32];
172 void fn23 (void);
173
174 __attribute__((noipa)) static void
175 fn24 (char *p)
176 {
177 if ((((__UINTPTR_TYPE__) p) & 15) != 0)
178 fn23 ();
179 asm ("");
180 }
181
182 void
183 fn25 (void)
184 {
185 fn24 (var2);
186 fn24 (var2 + 16);
187 }
188
189 /* { dg-final { scan-tree-dump "fn20 \\(\\)" "optimized" } } */