1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
2
3; Test that basic 32-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 float @llvm.fabs.f32(float)
9declare float @llvm.copysign.f32(float, float)
10declare float @llvm.sqrt.f32(float)
11declare float @llvm.ceil.f32(float)
12declare float @llvm.floor.f32(float)
13declare float @llvm.trunc.f32(float)
14declare float @llvm.nearbyint.f32(float)
15declare float @llvm.rint.f32(float)
16declare float @llvm.fma.f32(float, float, float)
17
18; CHECK-LABEL: fadd32:
19; CHECK-NEXT: .functype fadd32 (f32, f32) -> (f32){{$}}
20; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
21; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
22; CHECK-NEXT: f32.add $push[[LR:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
23; CHECK-NEXT: return $pop[[LR]]{{$}}
24define float @fadd32(float %x, float %y) {
25  %a = fadd float %x, %y
26  ret float %a
27}
28
29; CHECK-LABEL: fsub32:
30; CHECK: f32.sub $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
31; CHECK-NEXT: return $pop[[LR]]{{$}}
32define float @fsub32(float %x, float %y) {
33  %a = fsub float %x, %y
34  ret float %a
35}
36
37; CHECK-LABEL: fmul32:
38; CHECK: f32.mul $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
39; CHECK-NEXT: return $pop[[LR]]{{$}}
40define float @fmul32(float %x, float %y) {
41  %a = fmul float %x, %y
42  ret float %a
43}
44
45; CHECK-LABEL: fdiv32:
46; CHECK: f32.div $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
47; CHECK-NEXT: return $pop[[LR]]{{$}}
48define float @fdiv32(float %x, float %y) {
49  %a = fdiv float %x, %y
50  ret float %a
51}
52
53; CHECK-LABEL: fabs32:
54; CHECK: f32.abs $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
55; CHECK-NEXT: return $pop[[LR]]{{$}}
56define float @fabs32(float %x) {
57  %a = call float @llvm.fabs.f32(float %x)
58  ret float %a
59}
60
61; CHECK-LABEL: fneg32:
62; CHECK: f32.neg $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
63; CHECK-NEXT: return $pop[[LR]]{{$}}
64define float @fneg32(float %x) {
65  %a = fsub float -0., %x
66  ret float %a
67}
68
69; CHECK-LABEL: copysign32:
70; CHECK: f32.copysign $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
71; CHECK-NEXT: return $pop[[LR]]{{$}}
72define float @copysign32(float %x, float %y) {
73  %a = call float @llvm.copysign.f32(float %x, float %y)
74  ret float %a
75}
76
77; CHECK-LABEL: sqrt32:
78; CHECK: f32.sqrt $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
79; CHECK-NEXT: return $pop[[LR]]{{$}}
80define float @sqrt32(float %x) {
81  %a = call float @llvm.sqrt.f32(float %x)
82  ret float %a
83}
84
85; CHECK-LABEL: ceil32:
86; CHECK: f32.ceil $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
87; CHECK-NEXT: return $pop[[LR]]{{$}}
88define float @ceil32(float %x) {
89  %a = call float @llvm.ceil.f32(float %x)
90  ret float %a
91}
92
93; CHECK-LABEL: floor32:
94; CHECK: f32.floor $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
95; CHECK-NEXT: return $pop[[LR]]{{$}}
96define float @floor32(float %x) {
97  %a = call float @llvm.floor.f32(float %x)
98  ret float %a
99}
100
101; CHECK-LABEL: trunc32:
102; CHECK: f32.trunc $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
103; CHECK-NEXT: return $pop[[LR]]{{$}}
104define float @trunc32(float %x) {
105  %a = call float @llvm.trunc.f32(float %x)
106  ret float %a
107}
108
109; CHECK-LABEL: nearest32:
110; CHECK: f32.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
111; CHECK-NEXT: return $pop[[LR]]{{$}}
112define float @nearest32(float %x) {
113  %a = call float @llvm.nearbyint.f32(float %x)
114  ret float %a
115}
116
117; CHECK-LABEL: nearest32_via_rint:
118; CHECK: f32.nearest $push[[LR:[0-9]+]]=, $pop{{[0-9]+}}{{$}}
119; CHECK-NEXT: return $pop[[LR]]{{$}}
120define float @nearest32_via_rint(float %x) {
121  %a = call float @llvm.rint.f32(float %x)
122  ret float %a
123}
124
125; CHECK-LABEL: fmin32:
126; CHECK: f32.min $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
127; CHECK-NEXT: return $pop1{{$}}
128define float @fmin32(float %x) {
129  %a = fcmp ult float %x, 0.0
130  %b = select i1 %a, float %x, float 0.0
131  ret float %b
132}
133
134; CHECK-LABEL: fmax32:
135; CHECK: f32.max $push1=, $pop{{[0-9]+}}, $pop[[LR]]{{$}}
136; CHECK-NEXT: return $pop1{{$}}
137define float @fmax32(float %x) {
138  %a = fcmp ugt float %x, 0.0
139  %b = select i1 %a, float %x, float 0.0
140  ret float %b
141}
142
143; CHECK-LABEL: fmin32_intrinsic:
144; CHECK: f32.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
145; CHECK-NEXT: return $pop0{{$}}
146declare float @llvm.minimum.f32(float, float)
147define float @fmin32_intrinsic(float %x, float %y) {
148  %a = call float @llvm.minimum.f32(float %x, float %y)
149  ret float %a
150}
151
152; CHECK-LABEL: fminnum32_intrinsic:
153; CHECK: f32.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
154; CHECK-NEXT: return $pop0{{$}}
155declare float @llvm.minnum.f32(float, float)
156define float @fminnum32_intrinsic(float %x, float %y) {
157  %a = call nnan float @llvm.minnum.f32(float %x, float %y)
158  ret float %a
159}
160
161; CHECK-LABEL: fmax32_intrinsic:
162; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
163; CHECK-NEXT: return $pop0{{$}}
164declare float @llvm.maximum.f32(float, float)
165define float @fmax32_intrinsic(float %x, float %y) {
166  %a = call float @llvm.maximum.f32(float %x, float %y)
167  ret float %a
168}
169
170; CHECK-LABEL: fmaxnum32_intrinsic:
171; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
172; CHECK-NEXT: return $pop0{{$}}
173declare float @llvm.maxnum.f32(float, float)
174define float @fmaxnum32_intrinsic(float %x, float %y) {
175  %a = call nnan float @llvm.maxnum.f32(float %x, float %y)
176  ret float %a
177}
178
179; CHECK-LABEL: fma32:
180; CHECK: {{^}} call $push[[LR:[0-9]+]]=, fmaf, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
181; CHECK-NEXT: return $pop[[LR]]{{$}}
182define float @fma32(float %a, float %b, float %c) {
183  %d = call float @llvm.fma.f32(float %a, float %b, float %c)
184  ret float %d
185}
186