[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / WebAssembly / comparisons-f64.ll
blob03a85f4e7b8d05949e2d6c3a5f32d18d11a747a4
1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
3 ; Test that basic 64-bit floating-point comparison operations assemble as
4 ; expected.
6 target triple = "wasm32-unknown-unknown"
8 ; CHECK-LABEL: ord_f64:
9 ; CHECK-NEXT: .functype ord_f64 (f64, f64) -> (i32){{$}}
10 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
11 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
12 ; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
13 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
14 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
15 ; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
16 ; CHECK-NEXT: i32.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
17 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
18 define i32 @ord_f64(double %x, double %y) {
19   %a = fcmp ord double %x, %y
20   %b = zext i1 %a to i32
21   ret i32 %b
24 ; CHECK-LABEL: uno_f64:
25 ; CHECK-NEXT: .functype uno_f64 (f64, f64) -> (i32){{$}}
26 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
27 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
28 ; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
29 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
30 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
31 ; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
32 ; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
33 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
34 define i32 @uno_f64(double %x, double %y) {
35   %a = fcmp uno double %x, %y
36   %b = zext i1 %a to i32
37   ret i32 %b
40 ; CHECK-LABEL: oeq_f64:
41 ; CHECK-NEXT: .functype oeq_f64 (f64, f64) -> (i32){{$}}
42 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
43 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
44 ; CHECK-NEXT: f64.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
45 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
46 define i32 @oeq_f64(double %x, double %y) {
47   %a = fcmp oeq double %x, %y
48   %b = zext i1 %a to i32
49   ret i32 %b
52 ; CHECK-LABEL: une_f64:
53 ; CHECK: f64.ne $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
54 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
55 define i32 @une_f64(double %x, double %y) {
56   %a = fcmp une double %x, %y
57   %b = zext i1 %a to i32
58   ret i32 %b
61 ; CHECK-LABEL: olt_f64:
62 ; CHECK: f64.lt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
63 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
64 define i32 @olt_f64(double %x, double %y) {
65   %a = fcmp olt double %x, %y
66   %b = zext i1 %a to i32
67   ret i32 %b
70 ; CHECK-LABEL: ole_f64:
71 ; CHECK: f64.le $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
72 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
73 define i32 @ole_f64(double %x, double %y) {
74   %a = fcmp ole double %x, %y
75   %b = zext i1 %a to i32
76   ret i32 %b
79 ; CHECK-LABEL: ogt_f64:
80 ; CHECK: f64.gt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
81 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
82 define i32 @ogt_f64(double %x, double %y) {
83   %a = fcmp ogt double %x, %y
84   %b = zext i1 %a to i32
85   ret i32 %b
88 ; CHECK-LABEL: oge_f64:
89 ; CHECK: f64.ge $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
90 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
91 define i32 @oge_f64(double %x, double %y) {
92   %a = fcmp oge double %x, %y
93   %b = zext i1 %a to i32
94   ret i32 %b
97 ; Expanded comparisons, which also check for NaN.
99 ; CHECK-LABEL: ueq_f64:
100 ; CHECK-NEXT: .functype ueq_f64 (f64, f64) -> (i32){{$}}
101 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
102 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
103 ; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
104 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
105 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
106 ; CHECK-NEXT: f64.lt $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
107 ; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
108 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
109 ; CHECK-NEXT: i32.xor $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[C0]]{{$}}
110 ; CHECK-NEXT: return $pop[[NUM3]]{{$}}
111 define i32 @ueq_f64(double %x, double %y) {
112   %a = fcmp ueq double %x, %y
113   %b = zext i1 %a to i32
114   ret i32 %b
117 ; CHECK-LABEL: one_f64:
118 ; CHECK-NEXT: .functype one_f64 (f64, f64) -> (i32){{$}}
119 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
120 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
121 ; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
122 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
123 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
124 ; CHECK-NEXT: f64.lt $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
125 ; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
126 ; CHECK-NEXT: return $pop[[NUM4]]
127 define i32 @one_f64(double %x, double %y) {
128   %a = fcmp one double %x, %y
129   %b = zext i1 %a to i32
130   ret i32 %b
133 ; CHECK-LABEL: ult_f64:
134 ; CHECK-NEXT: .functype ult_f64 (f64, f64) -> (i32){{$}}
135 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
136 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
137 ; CHECK-NEXT: f64.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
138 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
139 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
140 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
141 define i32 @ult_f64(double %x, double %y) {
142   %a = fcmp ult double %x, %y
143   %b = zext i1 %a to i32
144   ret i32 %b
147 ; CHECK-LABEL: ule_f64:
148 ; CHECK-NEXT: .functype ule_f64 (f64, f64) -> (i32){{$}}
149 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
150 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
151 ; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
152 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
153 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
154 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
155 define i32 @ule_f64(double %x, double %y) {
156   %a = fcmp ule double %x, %y
157   %b = zext i1 %a to i32
158   ret i32 %b
161 ; CHECK-LABEL: ugt_f64:
162 ; CHECK-NEXT: .functype ugt_f64 (f64, f64) -> (i32){{$}}
163 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
164 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
165 ; CHECK-NEXT: f64.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
166 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
167 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
168 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
169 define i32 @ugt_f64(double %x, double %y) {
170   %a = fcmp ugt double %x, %y
171   %b = zext i1 %a to i32
172   ret i32 %b
175 ; CHECK-LABEL: uge_f64:
176 ; CHECK-NEXT: .functype uge_f64 (f64, f64) -> (i32){{$}}
177 ; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
178 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
179 ; CHECK-NEXT: f64.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
180 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
181 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
182 ; CHECK-NEXT: return $pop[[NUM2]]{{$}}
183 define i32 @uge_f64(double %x, double %y) {
184   %a = fcmp uge double %x, %y
185   %b = zext i1 %a to i32
186   ret i32 %b
189 ; CHECK-LABEL: olt_f64_branch:
190 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
191 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
192 ; CHECK-NEXT: f64.lt    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
193 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
194 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
195 ; CHECK-NEXT: call      call1
196 define void @olt_f64_branch(double %a, double %b) {
197 entry:
198   %cmp = fcmp olt double %a, %b
199   br i1 %cmp, label %if.then, label %if.end
201 if.then:
202   tail call void @call1()
203   br label %if.end
205 if.end:
206   ret void
209 ; CHECK-LABEL: ole_f64_branch:
210 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
211 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
212 ; CHECK-NEXT: f64.le    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
213 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
214 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
215 ; CHECK-NEXT: call      call1
216 define void @ole_f64_branch(double %a, double %b) {
217 entry:
218   %cmp = fcmp ole double %a, %b
219   br i1 %cmp, label %if.then, label %if.end
221 if.then:
222   tail call void @call1()
223   br label %if.end
225 if.end:
226   ret void
229 ; CHECK-LABEL: ugt_f64_branch:
230 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
231 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
232 ; CHECK-NEXT: f64.le    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
233 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
234 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
235 ; CHECK-NEXT: call      call1
236 define void @ugt_f64_branch(double %a, double %b) {
237 entry:
238   %cmp = fcmp ugt double %a, %b
239   br i1 %cmp, label %if.end, label %if.then
241 if.then:
242   tail call void @call1()
243   br label %if.end
245 if.end:
246   ret void
249 ; CHECK-LABEL: ogt_f64_branch:
250 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
251 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
252 ; CHECK-NEXT: f64.gt    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
253 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
254 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
255 ; CHECK-NEXT: call      call1
256 define void @ogt_f64_branch(double %a, double %b) {
257 entry:
258   %cmp = fcmp ogt double %a, %b
259   br i1 %cmp, label %if.then, label %if.end
261 if.then:
262   tail call void @call1()
263   br label %if.end
265 if.end:
266   ret void
269 ; CHECK-LABEL: ult_f64_branch:
270 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
271 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
272 ; CHECK-NEXT: f64.ge    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
273 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
274 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
275 ; CHECK-NEXT: call      call1
276 define void @ult_f64_branch(double %a, double %b) {
277 entry:
278   %cmp = fcmp ult double %a, %b
279   br i1 %cmp, label %if.end, label %if.then
281 if.then:
282   tail call void @call1()
283   br label %if.end
285 if.end:
286   ret void
289 ; CHECK-LABEL: ule_f64_branch:
290 ; CHECK:      local.get $push[[L0:[0-9]+]]=, 0
291 ; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1
292 ; CHECK-NEXT: f64.gt    $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]
293 ; CHECK-NEXT: i32.eqz   $push[[NUM3:[0-9]+]]=, $pop[[NUM0]]
294 ; CHECK-NEXT: br_if     0, $pop[[NUM3]]
295 ; CHECK-NEXT: call      call1
296 define void @ule_f64_branch(double %a, double %b) {
297 entry:
298   %cmp = fcmp ule double %a, %b
299   br i1 %cmp, label %if.end, label %if.then
301 if.then:
302   tail call void @call1()
303   br label %if.end
305 if.end:
306   ret void
309 ; CHECK-LABEL: xor_zext_switch
310 ; CHECK:      i32.const $push[[L1:[0-9]+]]=, 0
311 ; CHECK-NEXT: br_if     0, $pop[[L1]]
312 ; CHECK-NEXT: block
313 ; CHECK-NEXT: block
314 ; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0
315 ; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1
316 ; CHECK-NEXT: f64.ge    $push[[L0:[0-9]+]]=, $pop[[L3]], $pop[[L2]]
317 ; CHECK-NEXT: br_table  $pop[[L0]], 0, 1, 0
318 define void @xor_zext_switch(double %a, double %b) {
319 entry:
320   %cmp = fcmp ult double %a, %b
321   %zext = zext i1 %cmp to i32
322   %xor = xor i32 %zext, 1
323   switch i32 %xor, label %exit [
324     i32 0, label %sw.bb.1
325     i32 1, label %sw.bb.2
326   ]
328 sw.bb.1:
329   tail call void @foo1()
330   br label %exit
332 sw.bb.2:
333   tail call void @foo2()
334   br label %exit
336 exit:
337   ret void
340 ; CHECK-LABEL: xor_add_switch
341 ; CHECK:      local.get $push[[L8:[0-9]+]]=, 0
342 ; CHECK-NEXT: local.get $push[[L7:[0-9]+]]=, 1
343 ; CHECK-NEXT: f64.ge    $push[[L1:[0-9]+]]=, $pop[[L8]], $pop[[L7]]
344 ; CHECK-NEXT: i32.const $push[[L2:[0-9]+]]=, 1
345 ; CHECK-NEXT: i32.xor   $push[[L3:[0-9]+]]=, $pop[[L1]], $pop[[L2]]
346 ; CHECK-NEXT: i32.const $push[[L6:[0-9]+]]=, 1
347 ; CHECK-NEXT: i32.add   $push[[L4:[0-9]+]]=, $pop[[L3]], $pop[[L6]]
348 ; CHECK-NEXT: i32.const $push[[L5:[0-9]+]]=, 1
349 ; CHECK-NEXT: i32.xor   $push[[L0:[0-9]+]]=, $pop[[L4]], $pop[[L5]]
350 ; CHECK-NEXT: br_table  $pop[[L0]], 0, 1, 2, 3
351 define void @xor_add_switch(double %a, double %b) {
352 entry:
353   %cmp = fcmp ult double %a, %b
354   %zext = zext i1 %cmp to i32
355   %add = add nsw nuw i32 %zext, 1
356   %xor = xor i32 %add, 1
357   switch i32 %xor, label %exit [
358     i32 0, label %sw.bb.1
359     i32 1, label %sw.bb.2
360     i32 2, label %sw.bb.3
361   ]
363 sw.bb.1:
364   tail call void @foo1()
365   br label %exit
367 sw.bb.2:
368   tail call void @foo2()
369   br label %exit
371 sw.bb.3:
372   tail call void @foo3()
373   br label %exit
375 exit:
376   ret void
379 declare void @foo1()
380 declare void @foo2()
381 declare void @foo3()
382 declare void @call1()