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 |
3 | |
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 |
7 | |
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 |
10 | |
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 |
13 | |
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 |
17 | |
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 |
20 | |
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 |
24 | |
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 |
28 | |
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 |
31 | |
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 |
34 | |
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 |
38 | |
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 |
41 | |
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 |
45 | |
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 |
52 | |
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 |
55 | |
56 | void TestComparisons() { |
57 | short _Accum sa; |
58 | _Accum a; |
59 | unsigned short _Accum usa; |
60 | unsigned _Accum ua; |
61 | |
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, i16* %sa, align 2 |
66 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
70 | |
71 | sa != a; |
72 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
73 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
77 | |
78 | sa > a; |
79 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
80 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
84 | |
85 | sa >= a; |
86 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
87 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
91 | |
92 | sa < a; |
93 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
94 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
98 | |
99 | sa <= a; |
100 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
101 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
105 | |
106 | usa > ua; |
107 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
108 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
112 | |
113 | usa >= ua; |
114 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
115 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
119 | |
120 | usa < ua; |
121 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
122 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
126 | |
127 | usa <= ua; |
128 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
129 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
133 | } |
134 | |
135 | void TestIntComparisons() { |
136 | short _Accum sa; |
137 | unsigned short _Accum usa; |
138 | |
139 | int i; |
140 | unsigned int ui; |
141 | _Bool b; |
142 | char c; |
143 | short s; |
144 | enum E { |
145 | A = 2 |
146 | } e; |
147 | |
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, i16* %sa, align 2 |
152 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
157 | |
158 | sa != i; |
159 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
160 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
165 | |
166 | sa > i; |
167 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
168 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
173 | |
174 | sa >= i; |
175 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
176 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
181 | |
182 | sa < i; |
183 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
184 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
189 | |
190 | sa <= i; |
191 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
192 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
197 | |
198 | usa > ui; |
199 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
200 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
209 | |
210 | usa >= ui; |
211 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
212 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
221 | |
222 | usa < ui; |
223 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
224 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
233 | |
234 | usa <= ui; |
235 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
236 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
245 | |
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, i16* %sa, align 2 |
251 | // CHECK-NEXT: [[B:%[0-9]+]] = load i8, i8* %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]] |
258 | |
259 | sa == c; |
260 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
261 | // CHECK-NEXT: [[C:%[0-9]+]] = load i8, i8* %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]] |
267 | |
268 | sa == s; |
269 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
270 | // CHECK-NEXT: [[S:%[0-9]+]] = load i16, i16* %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]] |
276 | |
277 | // An enum value is IntegralCast to an unsigned int. |
278 | usa == e; |
279 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
280 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
289 | } |
290 | |
291 | void TestComparisonSignage() { |
292 | short _Accum sa; |
293 | unsigned short _Accum usa; |
294 | int i; |
295 | unsigned int ui; |
296 | |
297 | // Signed vs unsigned fixed point comparison |
298 | sa == usa; |
299 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
300 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, i16* %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]] |
306 | |
307 | // Signed int vs unsigned fixed point |
308 | sa == ui; |
309 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
310 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
315 | |
316 | // Signed fixed point vs unsigned int |
317 | usa == i; |
318 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2 |
319 | // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %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]] |
328 | } |
329 | |
330 | void TestSaturationComparisons() { |
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; |
336 | |
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, i16* %sat_sa, align 2 |
342 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
346 | |
347 | sat_sa == a; |
348 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sat_sa, align 2 |
349 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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]] |
353 | |
354 | sat_sa == sat_usa; |
355 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sat_sa, align 2 |
356 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, i16* %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]] |
362 | } |
363 | |
364 | void StoreBooleanResult() { |
365 | short _Accum sa; |
366 | _Accum a; |
367 | int res; |
368 | |
369 | // Check that the result can properly be stored as an int. |
370 | res = sa == a; |
371 | // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2 |
372 | // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %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, i32* %res, align 4 |
378 | } |
379 | |