• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 comparison operations assemble as
4; expected.
5
6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7target triple = "wasm32-unknown-unknown"
8
9; CHECK-LABEL: ord_f32:
10; CHECK-NEXT: .functype ord_f32 (f32, f32) -> (i32){{$}}
11; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
12; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
13; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
14; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
15; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
16; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
17; CHECK-NEXT: i32.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
18; CHECK-NEXT: return $pop[[NUM2]]{{$}}
19define i32 @ord_f32(float %x, float %y) {
20  %a = fcmp ord float %x, %y
21  %b = zext i1 %a to i32
22  ret i32 %b
23}
24
25; CHECK-LABEL: uno_f32:
26; CHECK-NEXT: .functype uno_f32 (f32, f32) -> (i32){{$}}
27; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
28; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}}
29; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
30; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 1{{$}}
31; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 1{{$}}
32; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
33; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
34; CHECK-NEXT: return $pop[[NUM2]]{{$}}
35define i32 @uno_f32(float %x, float %y) {
36  %a = fcmp uno float %x, %y
37  %b = zext i1 %a to i32
38  ret i32 %b
39}
40
41; CHECK-LABEL: oeq_f32:
42; CHECK-NEXT: .functype oeq_f32 (f32, f32) -> (i32){{$}}
43; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
44; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
45; CHECK-NEXT: f32.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
46; CHECK-NEXT: return $pop[[NUM]]{{$}}
47define i32 @oeq_f32(float %x, float %y) {
48  %a = fcmp oeq float %x, %y
49  %b = zext i1 %a to i32
50  ret i32 %b
51}
52
53; CHECK-LABEL: une_f32:
54; CHECK: f32.ne $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
55; CHECK-NEXT: return $pop[[NUM]]{{$}}
56define i32 @une_f32(float %x, float %y) {
57  %a = fcmp une float %x, %y
58  %b = zext i1 %a to i32
59  ret i32 %b
60}
61
62; CHECK-LABEL: olt_f32:
63; CHECK: f32.lt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
64; CHECK-NEXT: return $pop[[NUM]]{{$}}
65define i32 @olt_f32(float %x, float %y) {
66  %a = fcmp olt float %x, %y
67  %b = zext i1 %a to i32
68  ret i32 %b
69}
70
71; CHECK-LABEL: ole_f32:
72; CHECK: f32.le $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
73; CHECK-NEXT: return $pop[[NUM]]{{$}}
74define i32 @ole_f32(float %x, float %y) {
75  %a = fcmp ole float %x, %y
76  %b = zext i1 %a to i32
77  ret i32 %b
78}
79
80; CHECK-LABEL: ogt_f32:
81; CHECK: f32.gt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
82; CHECK-NEXT: return $pop[[NUM]]{{$}}
83define i32 @ogt_f32(float %x, float %y) {
84  %a = fcmp ogt float %x, %y
85  %b = zext i1 %a to i32
86  ret i32 %b
87}
88
89; CHECK-LABEL: oge_f32:
90; CHECK: f32.ge $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
91; CHECK-NEXT: return $pop[[NUM]]{{$}}
92define i32 @oge_f32(float %x, float %y) {
93  %a = fcmp oge float %x, %y
94  %b = zext i1 %a to i32
95  ret i32 %b
96}
97
98; Expanded comparisons, which also check for NaN.
99; These simply rely on SDAG's Expand cond code action.
100
101; CHECK-LABEL: ueq_f32:
102; CHECK-NEXT: .functype ueq_f32 (f32, f32) -> (i32){{$}}
103; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
104; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
105; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
106; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
107; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
108; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
109; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
110; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
111; CHECK-NEXT: f32.ne $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
112; CHECK-NEXT: i32.or $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
113; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
114; CHECK-NEXT: return $pop[[NUM4]]{{$}}
115define i32 @ueq_f32(float %x, float %y) {
116  %a = fcmp ueq float %x, %y
117  %b = zext i1 %a to i32
118  ret i32 %b
119}
120
121; CHECK-LABEL: one_f32:
122; CHECK-NEXT: .functype one_f32 (f32, f32) -> (i32){{$}}
123; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
124; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
125; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
126; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}}
127; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}}
128; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
129; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}}
130; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}}
131; CHECK-NEXT: f32.eq $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}}
132; CHECK-NEXT: i32.and $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}}
133; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}}
134; CHECK-NEXT: return $pop[[NUM4]]
135define i32 @one_f32(float %x, float %y) {
136  %a = fcmp one float %x, %y
137  %b = zext i1 %a to i32
138  ret i32 %b
139}
140
141; CHECK-LABEL: ult_f32:
142; CHECK-NEXT: .functype ult_f32 (f32, f32) -> (i32){{$}}
143; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
144; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
145; CHECK-NEXT: f32.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
146; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
147; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
148; CHECK-NEXT: return $pop[[NUM2]]{{$}}
149define i32 @ult_f32(float %x, float %y) {
150  %a = fcmp ult float %x, %y
151  %b = zext i1 %a to i32
152  ret i32 %b
153}
154
155; CHECK-LABEL: ule_f32:
156; CHECK-NEXT: .functype ule_f32 (f32, f32) -> (i32){{$}}
157; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
158; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
159; CHECK-NEXT: f32.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
160; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
161; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
162; CHECK-NEXT: return $pop[[NUM2]]{{$}}
163define i32 @ule_f32(float %x, float %y) {
164  %a = fcmp ule float %x, %y
165  %b = zext i1 %a to i32
166  ret i32 %b
167}
168
169; CHECK-LABEL: ugt_f32:
170; CHECK-NEXT: .functype ugt_f32 (f32, f32) -> (i32){{$}}
171; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
172; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
173; CHECK-NEXT: f32.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
174; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
175; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
176; CHECK-NEXT: return $pop[[NUM2]]{{$}}
177define i32 @ugt_f32(float %x, float %y) {
178  %a = fcmp ugt float %x, %y
179  %b = zext i1 %a to i32
180  ret i32 %b
181}
182
183; CHECK-LABEL: uge_f32:
184; CHECK-NEXT: .functype uge_f32 (f32, f32) -> (i32){{$}}
185; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
186; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
187; CHECK-NEXT: f32.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
188; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1
189; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}}
190; CHECK-NEXT: return $pop[[NUM2]]{{$}}
191define i32 @uge_f32(float %x, float %y) {
192  %a = fcmp uge float %x, %y
193  %b = zext i1 %a to i32
194  ret i32 %b
195}
196