xref: /llvm-project/clang/test/CodeGen/pragma-cx-limited-range.c (revision 94473f4db6a6f5f12d7c4081455b5b596094eac5)
1 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
2 // RUN: -o - | FileCheck %s --check-prefix=FULL
3 
4 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
5 // RUN: -complex-range=basic -o - | FileCheck --check-prefix=BASIC %s
6 
7 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
8 // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL
9 
10 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
11 // RUN: -complex-range=improved -o - | FileCheck --check-prefix=IMPRVD %s
12 
13 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
14 // RUN: -complex-range=promoted -o - | FileCheck --check-prefix=PRMTD %s
15 
16 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \
17 // RUN: -complex-range=full -o - | FileCheck --check-prefix=FULL %s
18 
19 _Complex float pragma_on_mul(_Complex float a, _Complex float b) {
20 #pragma STDC CX_LIMITED_RANGE ON
21   // LABEL: define {{.*}} @pragma_on_mul(
22 
23   // FULL: fmul float
24   // FULL-NEXT: fmul float
25   // FULL-NEXT: fmul float
26   // FULL-NEXT: fmul float
27   // FULL-NEXT: fsub float
28   // FULL-NEXT: fadd float
29 
30   // BASIC: fmul float
31   // BASIC-NEXT: fmul float
32   // BASIC-NEXT: fmul float
33   // BASIC-NEXT: fmul float
34   // BASIC-NEXT: fsub float
35   // BASIC-NEXT: fadd float
36 
37   // IMPRVD: fmul float
38   // IMPRVD-NEXT: fmul float
39   // IMPRVD-NEXT: fmul float
40   // IMPRVD-NEXT: fmul float
41   // IMPRVD-NEXT: fsub float
42   // IMPRVD-NEXT: fadd float
43 
44   // PRMTD: fmul float
45   // PRMTD-NEXT: fmul float
46   // PRMTD-NEXT: fmul float
47   // PRMTD-NEXT: fmul float
48   // PRMTD-NEXT: fsub float
49   // PRMTD-NEXT: fadd float
50 
51   return a * b;
52 }
53 
54 _Complex float pragma_off_mul(_Complex float a, _Complex float b) {
55 #pragma STDC CX_LIMITED_RANGE OFF
56   // LABEL: define {{.*}} @pragma_off_mul(
57 
58   // FULL: call {{.*}} @__mulsc3
59 
60   // BASIC: call {{.*}} @__mulsc3
61 
62   // IMPRVD: call {{.*}} @__mulsc3
63 
64   // PRMTD: call {{.*}} @__mulsc3
65 
66   return a * b;
67 }
68 
69 _Complex float pragma_on_div(_Complex float a, _Complex float b) {
70 #pragma STDC CX_LIMITED_RANGE ON
71   // LABEL: define {{.*}} @pragma_on_div(
72 
73   // FULL: fmul float
74   // FULL-NEXT: fmul float
75   // FULL-NEXT: fadd float
76   // FULL-NEXT: fmul float
77   // FULL-NEXT: fmul float
78   // FULL-NEXT: fadd float
79   // FULL-NEXT: fmul float
80   // FULL-NEXT: fmul float
81   // FULL-NEXT: fsub float
82   // FULL-NEXT: fdiv float
83   // FULL: fdiv float
84 
85   // BASIC: fmul float
86   // BASIC-NEXT: fmul float
87   // BASIC-NEXT: fadd float
88   // BASIC-NEXT: fmul float
89   // BASIC-NEXT: fmul float
90   // BASIC-NEXT: fadd float
91   // BASIC-NEXT: fmul float
92   // BASIC-NEXT: fmul float
93   // BASIC-NEXT: fsub float
94   // BASIC-NEXT: fdiv float
95   // BASIC-NEXT: fdiv float
96 
97   // IMPRVD: fmul float
98   // IMPRVD-NEXT: fmul float
99   // IMPRVD-NEXT: fadd float
100   // IMPRVD-NEXT: fmul float
101   // IMPRVD-NEXT: fmul float
102   // IMPRVD-NEXT: fadd float
103   // IMPRVD-NEXT: fmul float
104   // IMPRVD-NEXT: fmul float
105   // IMPRVD-NEXT: fsub float
106   // IMPRVD-NEXT: fdiv float
107   // IMPRVD-NEXT: fdiv float
108 
109   // PRMTD: fmul float
110   // PRMTD-NEXT: fmul float
111   // PRMTD-NEXT: fadd float
112   // PRMTD-NEXT: fmul float
113   // PRMTD-NEXT: fmul float
114   // PRMTD-NEXT: fadd float
115   // PRMTD-NEXT: fmul float
116   // PRMTD-NEXT: fmul float
117   // PRMTD-NEXT: fsub float
118   // PRMTD-NEXT: fdiv float
119   // PRMTD-NEXT: fdiv float
120 
121   return a / b;
122 }
123 
124 _Complex float pragma_off_div(_Complex float a, _Complex float b) {
125 #pragma STDC CX_LIMITED_RANGE OFF
126   // LABEL: define {{.*}} @pragma_off_div(
127 
128   // FULL: call {{.*}} @__divsc3
129 
130   // BASIC: call {{.*}} @__divsc3
131 
132   // IMPRVD: call {{.*}} @__divsc3
133 
134   // PRMTD: call {{.*}} @__divsc3
135 
136   return a / b;
137 }
138 
139 _Complex float pragma_default_mul(_Complex float a, _Complex float b) {
140 #pragma STDC CX_LIMITED_RANGE DEFAULT
141   // LABEL: define {{.*}} @pragma_on_mul(
142 
143   // FULL: fmul float
144   // FULL-NEXT: fmul float
145   // FULL-NEXT: fmul float
146   // FULL-NEXT: fmul float
147   // FULL-NEXT: fsub float
148   // FULL-NEXT: fadd float
149 
150   // BASIC: fmul float
151   // BASIC-NEXT: fmul float
152   // BASIC-NEXT: fmul float
153   // BASIC-NEXT: fmul float
154   // BASIC-NEXT: fsub float
155   // BASIC-NEXT: fadd float
156 
157   // IMPRVD: fmul float
158   // IMPRVD-NEXT: fmul float
159   // IMPRVD-NEXT: fmul float
160   // IMPRVD-NEXT: fmul float
161   // IMPRVD-NEXT: fsub float
162   // IMPRVD-NEXT: fadd float
163 
164   // PRMTD: fmul float
165   // PRMTD-NEXT: fmul float
166   // PRMTD-NEXT: fmul float
167   // PRMTD-NEXT: fmul float
168   // PRMTD-NEXT: fsub float
169   // PRMTD-NEXT: fadd float
170 
171   return a * b;
172 }
173 _Complex float pragma_default_div(_Complex float a, _Complex float b) {
174 #pragma STDC CX_LIMITED_RANGE DEFAULT
175   // LABEL: define {{.*}} @pragma_on_divx(
176 
177   // FULL: call {{.*}} @__divsc3
178 
179   // BASIC: fmul float
180   // BASIC-NEXT: fmul float
181   // BASIC-NEXT: fadd float
182   // BASIC-NEXT: fmul float
183   // BASIC-NEXT: fmul float
184   // BASIC-NEXT: fadd float
185   // BASIC-NEXT: fmul float
186   // BASIC-NEXT: fmul float
187   // BASIC-NEXT: fsub float
188   // BASIC-NEXT: fdiv float
189   // BASIC-NEXT: fdiv float
190 
191   // IMPRVD: call{{.*}}float @llvm.fabs.f32(float {{.*}})
192   // IMPRVD-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}})
193   // IMPRVD-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}}
194   // IMPRVD-NEXT:   br i1 {{.*}}, label
195   // IMPRVD:  abs_rhsr_greater_or_equal_abs_rhsi:
196   // IMPRVD-NEXT: fdiv float
197   // IMPRVD-NEXT: fmul float
198   // IMPRVD-NEXT: fadd float
199   // IMPRVD-NEXT: fmul float
200   // IMPRVD-NEXT: fadd float
201   // IMPRVD-NEXT: fdiv float
202   // IMPRVD-NEXT: fmul float
203   // IMPRVD-NEXT: fsub float
204   // IMPRVD-NEXT: fdiv float
205   // IMPRVD-NEXT: br label
206   // IMPRVD: abs_rhsr_less_than_abs_rhsi:
207   // IMPRVD-NEXT: fdiv float
208   // IMPRVD-NEXT: fmul float
209   // IMPRVD-NEXT: fadd float
210   // IMPRVD-NEXT: fmul float
211   // IMPRVD-NEXT: fadd float
212   // IMPRVD-NEXT: fdiv float
213   // IMPRVD-NEXT: fmul float
214   // IMPRVD-NEXT: fsub float
215   // IMPRVD-NEXT: fdiv float
216 
217   // PRMTD: load float, ptr {{.*}}
218   // PRMTD: fpext float {{.*}} to double
219   // PRMTD-NEXT: fpext float {{.*}} to double
220   // PRMTD-NEXT: getelementptr inbounds nuw { float, float }, ptr {{.*}}, i32 0, i32 0
221   // PRMTD-NEXT: load float, ptr {{.*}}
222   // PRMTD-NEXT: getelementptr inbounds nuw { float, float }, ptr {{.*}}, i32 0, i32 1
223   // PRMTD-NEXT: load float, ptr {{.*}}
224   // PRMTD-NEXT: fpext float {{.*}} to double
225   // PRMTD-NEXT: fpext float {{.*}} to double
226   // PRMTD-NEXT: fmul double
227   // PRMTD-NEXT: fmul double
228   // PRMTD-NEXT: fadd double
229   // PRMTD-NEXT: fmul double
230   // PRMTD-NEXT: fmul double
231   // PRMTD-NEXT: fadd double
232   // PRMTD-NEXT: fmul double
233   // PRMTD-NEXT: fmul double
234   // PRMTD-NEXT: fsub double
235   // PRMTD-NEXT: fdiv double
236   // PRMTD-NEXT: fdiv double
237   // PRMTD-NEXT: fptrunc double {{.*}} to float
238   // PRMTD-NEXT: fptrunc double {{.*}} to float
239 
240   return a / b;
241 }
242