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