1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
2
3; Test that basic 64-bit floating-point operations assemble as expected.
4
5target triple = "wasm32-unknown-unknown"
6
7declare double @llvm.fabs.f64(double)
8declare double @llvm.copysign.f64(double, double)
9declare double @llvm.sqrt.f64(double)
10declare double @llvm.ceil.f64(double)
11declare double @llvm.floor.f64(double)
12declare double @llvm.trunc.f64(double)
13declare double @llvm.nearbyint.f64(double)
14declare double @llvm.rint.f64(double)
15declare double @llvm.fma.f64(double, double, double)
16
17; CHECK-LABEL: fadd64:
18; CHECK-NEXT: .functype fadd64 (f64, f64) -> (f64){{$}}
19; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
20; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
21; CHECK-NEXT: f64.add $push[[LR:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
22; CHECK-NEXT: return $pop[[LR]]{{$}}
23define double @fadd64(double %x, double %y) {
24  %a = fadd double %x, %y
25  ret double %a
26}
27
28; CHECK-LABEL: fsub64:
29; CHECK: f64.sub $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
30; CHECK-NEXT: return $pop[[LR]]{{$}}
31define double @fsub64(double %x, double %y) {
32  %a = fsub double %x, %y
33  ret double %a
34}
35
36; CHECK-LABEL: fmul64:
37; CHECK: f64.mul $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
38; CHECK-NEXT: return $pop[[LR]]{{$}}
39define double @fmul64(double %x, double %y) {
40  %a = fmul double %x, %y
41  ret double %a
42}
43
44; CHECK-LABEL: fdiv64:
45; CHECK: f64.div $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
46; CHECK-NEXT: return $pop[[LR]]{{$}}
47define double @fdiv64(double %x, double %y) {
48  %a = fdiv double %x, %y
49  ret double %a
50}
51
52; CHECK-LABEL: fabs64:
53; CHECK: f64.abs $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
54; CHECK-NEXT: return $pop[[LR]]{{$}}
55define double @fabs64(double %x) {
56  %a = call double @llvm.fabs.f64(double %x)
57  ret double %a
58}
59
60; CHECK-LABEL: fneg64:
61; CHECK: f64.neg $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
62; CHECK-NEXT: return $pop[[LR]]{{$}}
63define double @fneg64(double %x) {
64  %a = fsub double -0., %x
65  ret double %a
66}
67
68; CHECK-LABEL: copysign64:
69; CHECK: f64.copysign $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
70; CHECK-NEXT: return $pop[[LR]]{{$}}
71define double @copysign64(double %x, double %y) {
72  %a = call double @llvm.copysign.f64(double %x, double %y)
73  ret double %a
74}
75
76; CHECK-LABEL: sqrt64:
77; CHECK: f64.sqrt $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
78; CHECK-NEXT: return $pop[[LR]]{{$}}
79define double @sqrt64(double %x) {
80  %a = call double @llvm.sqrt.f64(double %x)
81  ret double %a
82}
83
84; CHECK-LABEL: ceil64:
85; CHECK: f64.ceil $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
86; CHECK-NEXT: return $pop[[LR]]{{$}}
87define double @ceil64(double %x) {
88  %a = call double @llvm.ceil.f64(double %x)
89  ret double %a
90}
91
92; CHECK-LABEL: floor64:
93; CHECK: f64.floor $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
94; CHECK-NEXT: return $pop[[LR]]{{$}}
95define double @floor64(double %x) {
96  %a = call double @llvm.floor.f64(double %x)
97  ret double %a
98}
99
100; CHECK-LABEL: trunc64:
101; CHECK: f64.trunc $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
102; CHECK-NEXT: return $pop[[LR]]{{$}}
103define double @trunc64(double %x) {
104  %a = call double @llvm.trunc.f64(double %x)
105  ret double %a
106}
107
108; CHECK-LABEL: nearest64:
109; CHECK: f64.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
110; CHECK-NEXT: return $pop[[LR]]{{$}}
111define double @nearest64(double %x) {
112  %a = call double @llvm.nearbyint.f64(double %x)
113  ret double %a
114}
115
116; CHECK-LABEL: nearest64_via_rint:
117; CHECK: f64.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
118; CHECK-NEXT: return $pop[[LR]]{{$}}
119define double @nearest64_via_rint(double %x) {
120  %a = call double @llvm.rint.f64(double %x)
121  ret double %a
122}
123
124; CHECK-LABEL: fmin64:
125; CHECK: f64.min $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
126; CHECK-NEXT: return $pop1{{$}}
127define double @fmin64(double %x) {
128  %a = fcmp ult double %x, 0.0
129  %b = select i1 %a, double %x, double 0.0
130  ret double %b
131}
132
133; CHECK-LABEL: fmax64:
134; CHECK: f64.max $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
135; CHECK-NEXT: return $pop1{{$}}
136define double @fmax64(double %x) {
137  %a = fcmp ugt double %x, 0.0
138  %b = select i1 %a, double %x, double 0.0
139  ret double %b
140}
141
142; CHECK-LABEL: fmin64_intrinsic:
143; CHECK: f64.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
144; CHECK-NEXT: return $pop0{{$}}
145declare double @llvm.minimum.f64(double, double)
146define double @fmin64_intrinsic(double %x, double %y) {
147  %a = call double @llvm.minimum.f64(double %x, double %y)
148  ret double %a
149}
150
151; CHECK-LABEL: fmax64_intrinsic:
152; CHECK: f64.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
153; CHECK-NEXT: return $pop0{{$}}
154declare double @llvm.maximum.f64(double, double)
155define double @fmax64_intrinsic(double %x, double %y) {
156  %a = call double @llvm.maximum.f64(double %x, double %y)
157  ret double %a
158}
159
160; CHECK-LABEL: fma64:
161; CHECK: {{^}} call $push[[LR:[0-9]+]]=, fma, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
162; CHECK-NEXT: return $pop[[LR]]{{$}}
163define double @fma64(double %a, double %b, double %c) {
164  %d = call double @llvm.fma.f64(double %a, double %b, double %c)
165  ret double %d
166}
167