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