[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Frontend / fixed_point_comparisons.c
bloba59f06b9c9420e6ba6967178b38b718a04d56dc2
1 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNPADDED
2 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PADDED
4 // Fixed point against other fixed point
5 _Bool b_eq_true = 2.5hk == 2.5uhk; // CHECK-DAG: @b_eq_true = {{.*}}global i8 1, align 1
6 _Bool b_eq_false = 2.5hk == 2.4uhk; // CHECK-DAG: @b_eq_false = {{.*}}global i8 0, align 1
8 _Bool b_ne_true = 2.5hk != 2.4uhk; // CHECK-DAG: @b_ne_true = {{.*}}global i8 1, align 1
9 _Bool b_ne_false = 2.5hk != 2.5uhk; // CHECK-DAG: @b_ne_false = {{.*}}global i8 0, align 1
11 _Bool b_lt_true = 2.5hk < 2.75uhk; // CHECK-DAG: @b_lt_true = {{.*}}global i8 1, align 1
12 _Bool b_lt_false = 2.5hk < 2.5uhk; // CHECK-DAG: @b_lt_false = {{.*}}global i8 0, align 1
14 _Bool b_le_true = 2.5hk <= 2.75uhk; // CHECK-DAG: @b_le_true = {{.*}}global i8 1, align 1
15 _Bool b_le_true2 = 2.5hk <= 2.5uhk; // CHECK-DAG: @b_le_true2 = {{.*}}global i8 1, align 1
16 _Bool b_le_false = 2.5hk <= 2.4uhk; // CHECK-DAG: @b_le_false = {{.*}}global i8 0, align 1
18 _Bool b_gt_true = 2.75hk > 2.5uhk; // CHECK-DAG: @b_gt_true = {{.*}}global i8 1, align 1
19 _Bool b_gt_false = 2.75hk > 2.75uhk; // CHECK-DAG: @b_gt_false = {{.*}}global i8 0, align 1
21 _Bool b_ge_true = 2.75hk >= 2.5uhk; // CHECK-DAG: @b_ge_true = {{.*}}global i8 1, align 1
22 _Bool b_ge_true2 = 2.75hk >= 2.75uhk; // CHECK-DAG: @b_ge_true2 = {{.*}}global i8 1, align 1
23 _Bool b_ge_false = 2.5hk >= 2.75uhk; // CHECK-DAG: @b_ge_false = {{.*}}global i8 0, align 1
25 // Fixed point against int
26 _Bool b_ieq_true = 2.0hk == 2; // CHECK-DAG: @b_ieq_true = {{.*}}global i8 1, align 1
27 _Bool b_ieq_false = 2.0hk == 3; // CHECK-DAG: @b_ieq_false = {{.*}}global i8 0, align 1
29 _Bool b_ine_true = 2.0hk != 3; // CHECK-DAG: @b_ine_true = {{.*}}global i8 1, align 1
30 _Bool b_ine_false = 2.0hk != 2; // CHECK-DAG: @b_ine_false = {{.*}}global i8 0, align 1
32 _Bool b_ilt_true = 2.0hk < 3; // CHECK-DAG: @b_ilt_true = {{.*}}global i8 1, align 1
33 _Bool b_ilt_false = 2.0hk < 2; // CHECK-DAG: @b_ilt_false = {{.*}}global i8 0, align 1
35 _Bool b_ile_true = 2.0hk <= 3; // CHECK-DAG: @b_ile_true = {{.*}}global i8 1, align 1
36 _Bool b_ile_true2 = 2.0hk <= 2; // CHECK-DAG: @b_ile_true2 = {{.*}}global i8 1, align 1
37 _Bool b_ile_false = 2.0hk <= 1; // CHECK-DAG: @b_ile_false = {{.*}}global i8 0, align 1
39 _Bool b_igt_true = 2.0hk > 1; // CHECK-DAG: @b_igt_true = {{.*}}global i8 1, align 1
40 _Bool b_igt_false = 2.0hk > 2; // CHECK-DAG: @b_igt_false = {{.*}}global i8 0, align 1
42 _Bool b_ige_true = 2.0hk >= 1; // CHECK-DAG: @b_ige_true = {{.*}}global i8 1, align 1
43 _Bool b_ige_true2 = 2.0hk >= 2; // CHECK-DAG: @b_ige_true2 = {{.*}}global i8 1, align 1
44 _Bool b_ige_false = 2.0hk >= 3; // CHECK-DAG: @b_ige_false = {{.*}}global i8 0, align 1
46 // Different signage
47 // Since we can have different precisions, non powers of 2 fractions may have
48 // different actual values when being compared.
49 _Bool b_sne_true = 2.6hk != 2.6uhk;
50 // UNPADDED-DAG: @b_sne_true = {{.*}}global i8 1, align 1
51 // PADDED-DAG: @b_sne_true = {{.*}}global i8 0, align 1
53 _Bool b_seq_true = 2.0hk == 2u; // CHECK-DAG: @b_seq_true = {{.*}}global i8 1, align 1
54 _Bool b_seq_true2 = 2.0uhk == 2; // CHECK-DAG: @b_seq_true2 = {{.*}}global i8 1, align 1
56 void TestComparisons(void) {
57 short _Accum sa;
58 _Accum a;
59 unsigned short _Accum usa;
60 unsigned _Accum ua;
62 // Each of these should be a fixed point conversion followed by the actual
63 // comparison operation.
64 sa == a;
65 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
66 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
67 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
68 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
69 // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
71 sa != a;
72 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
73 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
74 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
75 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
76 // CHECK-NEXT: {{.*}} = icmp ne i32 [[UPSCALE_A]], [[A2]]
78 sa > a;
79 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
80 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
81 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
82 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
83 // CHECK-NEXT: {{.*}} = icmp sgt i32 [[UPSCALE_A]], [[A2]]
85 sa >= a;
86 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
87 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
88 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
89 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
90 // CHECK-NEXT: {{.*}} = icmp sge i32 [[UPSCALE_A]], [[A2]]
92 sa < a;
93 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
94 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
95 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
96 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
97 // CHECK-NEXT: {{.*}} = icmp slt i32 [[UPSCALE_A]], [[A2]]
99 sa <= a;
100 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
101 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
102 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
103 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
104 // CHECK-NEXT: {{.*}} = icmp sle i32 [[UPSCALE_A]], [[A2]]
106 usa > ua;
107 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
108 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %ua, align 4
109 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
110 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
111 // CHECK-NEXT: {{.*}} = icmp ugt i32 [[UPSCALE_A]], [[A2]]
113 usa >= ua;
114 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
115 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %ua, align 4
116 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
117 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
118 // CHECK-NEXT: {{.*}} = icmp uge i32 [[UPSCALE_A]], [[A2]]
120 usa < ua;
121 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
122 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %ua, align 4
123 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
124 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
125 // CHECK-NEXT: {{.*}} = icmp ult i32 [[UPSCALE_A]], [[A2]]
127 usa <= ua;
128 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
129 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %ua, align 4
130 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
131 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
132 // CHECK-NEXT: {{.*}} = icmp ule i32 [[UPSCALE_A]], [[A2]]
135 void TestIntComparisons(void) {
136 short _Accum sa;
137 unsigned short _Accum usa;
139 int i;
140 unsigned int ui;
141 _Bool b;
142 char c;
143 short s;
144 enum E {
145 A = 2
146 } e;
148 // These comparisons shouldn't be that different from comparing against fixed
149 // point types with other fixed point types.
150 sa == i;
151 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
152 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
153 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
154 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
155 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
156 // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
158 sa != i;
159 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
160 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
161 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
162 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
163 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
164 // CHECK-NEXT: {{.*}} = icmp ne i39 [[RESIZE_A]], [[UPSCALE_I]]
166 sa > i;
167 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
168 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
169 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
170 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
171 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
172 // CHECK-NEXT: {{.*}} = icmp sgt i39 [[RESIZE_A]], [[UPSCALE_I]]
174 sa >= i;
175 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
176 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
177 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
178 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
179 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
180 // CHECK-NEXT: {{.*}} = icmp sge i39 [[RESIZE_A]], [[UPSCALE_I]]
182 sa < i;
183 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
184 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
185 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
186 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
187 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
188 // CHECK-NEXT: {{.*}} = icmp slt i39 [[RESIZE_A]], [[UPSCALE_I]]
190 sa <= i;
191 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
192 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
193 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
194 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
195 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
196 // CHECK-NEXT: {{.*}} = icmp sle i39 [[RESIZE_A]], [[UPSCALE_I]]
198 usa > ui;
199 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
200 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %ui, align 4
201 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
202 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
203 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
204 // UNPADDED-NEXT: {{.*}} = icmp ugt i40 [[RESIZE_A]], [[UPSCALE_I]]
205 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
206 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
207 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
208 // PADDED-NEXT: {{.*}} = icmp ugt i39 [[RESIZE_A]], [[UPSCALE_I]]
210 usa >= ui;
211 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
212 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %ui, align 4
213 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
214 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
215 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
216 // UNPADDED-NEXT: {{.*}} = icmp uge i40 [[RESIZE_A]], [[UPSCALE_I]]
217 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
218 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
219 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
220 // PADDED-NEXT: {{.*}} = icmp uge i39 [[RESIZE_A]], [[UPSCALE_I]]
222 usa < ui;
223 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
224 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %ui, align 4
225 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
226 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
227 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
228 // UNPADDED-NEXT: {{.*}} = icmp ult i40 [[RESIZE_A]], [[UPSCALE_I]]
229 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
230 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
231 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
232 // PADDED-NEXT: {{.*}} = icmp ult i39 [[RESIZE_A]], [[UPSCALE_I]]
234 usa <= ui;
235 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
236 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %ui, align 4
237 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
238 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
239 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
240 // UNPADDED-NEXT: {{.*}} = icmp ule i40 [[RESIZE_A]], [[UPSCALE_I]]
241 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
242 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
243 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
244 // PADDED-NEXT: {{.*}} = icmp ule i39 [[RESIZE_A]], [[UPSCALE_I]]
246 // Allow for comparisons with other int like types. These are no different
247 // from comparing to an int other than varying sizes. The integer types are
248 // still converted to ints or unsigned ints from UsualUnaryConversions().
249 sa == b;
250 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
251 // CHECK-NEXT: [[B:%[0-9]+]] = load i8, ptr %b, align 1
252 // CHECK-NEXT: %tobool = trunc i8 [[B]] to i1
253 // CHECK-NEXT: [[CONV_B:%[a-z0-9]+]] = zext i1 %tobool to i32
254 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
255 // CHECK-NEXT: [[RESIZE_B:%[a-z0-9]+]] = sext i32 [[CONV_B]] to i39
256 // CHECK-NEXT: [[UPSCALE_B:%[a-z0-9]+]] = shl i39 [[RESIZE_B]], 7
257 // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_B]]
259 sa == c;
260 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
261 // CHECK-NEXT: [[C:%[0-9]+]] = load i8, ptr %c, align 1
262 // CHECK-NEXT: [[CONV_C:%[a-z0-9]+]] = sext i8 [[C]] to i32
263 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
264 // CHECK-NEXT: [[RESIZE_C:%[a-z0-9]+]] = sext i32 [[CONV_C]] to i39
265 // CHECK-NEXT: [[UPSCALE_C:%[a-z0-9]+]] = shl i39 [[RESIZE_C]], 7
266 // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_C]]
268 sa == s;
269 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
270 // CHECK-NEXT: [[S:%[0-9]+]] = load i16, ptr %s, align 2
271 // CHECK-NEXT: [[CONV_S:%[a-z0-9]+]] = sext i16 [[S]] to i32
272 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
273 // CHECK-NEXT: [[RESIZE_S:%[a-z0-9]+]] = sext i32 [[CONV_S]] to i39
274 // CHECK-NEXT: [[UPSCALE_S:%[a-z0-9]+]] = shl i39 [[RESIZE_S]], 7
275 // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_S]]
277 // An enum value is IntegralCast to an unsigned int.
278 usa == e;
279 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
280 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %e, align 4
281 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
282 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
283 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
284 // UNPADDED-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
285 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
286 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
287 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
288 // PADDED-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
291 void TestComparisonSignage(void) {
292 short _Accum sa;
293 unsigned short _Accum usa;
294 int i;
295 unsigned int ui;
297 // Signed vs unsigned fixed point comparison
298 sa == usa;
299 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
300 // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, ptr %usa, align 2
301 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i17
302 // UNPADDED-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i17 [[RESIZE_A]], 1
303 // UNPADDED-NEXT: [[RESIZE_A2:%[a-z0-9]+]] = zext i16 [[A2]] to i17
304 // UNPADDED-NEXT: {{.*}} = icmp eq i17 [[UPSCALE_A]], [[RESIZE_A2]]
305 // PADDED-NEXT: {{.*}} = icmp eq i16 [[A]], [[A2]]
307 // Signed int vs unsigned fixed point
308 sa == ui;
309 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
310 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %ui, align 4
311 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i40
312 // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
313 // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 7
314 // CHECK-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
316 // Signed fixed point vs unsigned int
317 usa == i;
318 // CHECK: [[A:%[0-9]+]] = load i16, ptr %usa, align 2
319 // CHECK-NEXT: [[I:%[0-9]+]] = load i32, ptr %i, align 4
320 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
321 // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i40
322 // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
323 // UNPADDED-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
324 // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
325 // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
326 // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
327 // PADDED-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
330 void TestSaturationComparisons(void) {
331 short _Accum sa;
332 _Accum a;
333 _Sat short _Accum sat_sa;
334 _Sat _Accum sat_a;
335 _Sat unsigned short _Accum sat_usa;
337 // These are effectively the same as conversions with their non-saturating
338 // counterparts since when comparing, we convert both operands to a common
339 // type that should be able to hold both values.
340 sat_sa == sat_a;
341 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sat_sa, align 2
342 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %sat_a, align 4
343 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
344 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
345 // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
347 sat_sa == a;
348 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sat_sa, align 2
349 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
350 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
351 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
352 // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
354 sat_sa == sat_usa;
355 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sat_sa, align 2
356 // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, ptr %sat_usa, align 2
357 // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i17
358 // UNPADDED-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i17 [[RESIZE_A]], 1
359 // UNPADDED-NEXT: [[RESIZE_A2:%[a-z0-9]+]] = zext i16 [[A2]] to i17
360 // UNPADDED-NEXT: {{.*}} = icmp eq i17 [[UPSCALE_A]], [[RESIZE_A2]]
361 // PADDED-NEXT: {{.*}} = icmp eq i16 [[A]], [[A2]]
364 void StoreBooleanResult(void) {
365 short _Accum sa;
366 _Accum a;
367 int res;
369 // Check that the result can properly be stored as an int.
370 res = sa == a;
371 // CHECK: [[A:%[0-9]+]] = load i16, ptr %sa, align 2
372 // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, ptr %a, align 4
373 // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
374 // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
375 // CHECK-NEXT: [[RES:%[0-9]+]] = icmp eq i32 [[UPSCALE_A]], [[A2]]
376 // CHECK-NEXT: %conv = zext i1 [[RES]] to i32
377 // CHECK-NEXT: store i32 %conv, ptr %res, align 4