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 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_f64: 10; CHECK-NEXT: .functype ord_f64 (f64, f64) -> (i32){{$}} 11; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 12; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}} 13; CHECK-NEXT: f64.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: f64.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_f64(double %x, double %y) { 20 %a = fcmp ord double %x, %y 21 %b = zext i1 %a to i32 22 ret i32 %b 23} 24 25; CHECK-LABEL: uno_f64: 26; CHECK-NEXT: .functype uno_f64 (f64, f64) -> (i32){{$}} 27; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 28; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 0{{$}} 29; CHECK-NEXT: f64.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: f64.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_f64(double %x, double %y) { 36 %a = fcmp uno double %x, %y 37 %b = zext i1 %a to i32 38 ret i32 %b 39} 40 41; CHECK-LABEL: oeq_f64: 42; CHECK-NEXT: .functype oeq_f64 (f64, f64) -> (i32){{$}} 43; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 44; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 45; CHECK-NEXT: f64.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 46; CHECK-NEXT: return $pop[[NUM]]{{$}} 47define i32 @oeq_f64(double %x, double %y) { 48 %a = fcmp oeq double %x, %y 49 %b = zext i1 %a to i32 50 ret i32 %b 51} 52 53; CHECK-LABEL: une_f64: 54; CHECK: f64.ne $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 55; CHECK-NEXT: return $pop[[NUM]]{{$}} 56define i32 @une_f64(double %x, double %y) { 57 %a = fcmp une double %x, %y 58 %b = zext i1 %a to i32 59 ret i32 %b 60} 61 62; CHECK-LABEL: olt_f64: 63; CHECK: f64.lt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 64; CHECK-NEXT: return $pop[[NUM]]{{$}} 65define i32 @olt_f64(double %x, double %y) { 66 %a = fcmp olt double %x, %y 67 %b = zext i1 %a to i32 68 ret i32 %b 69} 70 71; CHECK-LABEL: ole_f64: 72; CHECK: f64.le $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 73; CHECK-NEXT: return $pop[[NUM]]{{$}} 74define i32 @ole_f64(double %x, double %y) { 75 %a = fcmp ole double %x, %y 76 %b = zext i1 %a to i32 77 ret i32 %b 78} 79 80; CHECK-LABEL: ogt_f64: 81; CHECK: f64.gt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 82; CHECK-NEXT: return $pop[[NUM]]{{$}} 83define i32 @ogt_f64(double %x, double %y) { 84 %a = fcmp ogt double %x, %y 85 %b = zext i1 %a to i32 86 ret i32 %b 87} 88 89; CHECK-LABEL: oge_f64: 90; CHECK: f64.ge $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 91; CHECK-NEXT: return $pop[[NUM]]{{$}} 92define i32 @oge_f64(double %x, double %y) { 93 %a = fcmp oge double %x, %y 94 %b = zext i1 %a to i32 95 ret i32 %b 96} 97 98; Expanded comparisons, which also check for NaN. 99 100; CHECK-LABEL: ueq_f64: 101; CHECK-NEXT: .functype ueq_f64 (f64, f64) -> (i32){{$}} 102; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 103; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 104; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 105; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}} 106; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}} 107; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 108; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}} 109; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}} 110; CHECK-NEXT: f64.ne $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 111; CHECK-NEXT: i32.or $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}} 112; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}} 113; CHECK-NEXT: return $pop[[NUM4]]{{$}} 114define i32 @ueq_f64(double %x, double %y) { 115 %a = fcmp ueq double %x, %y 116 %b = zext i1 %a to i32 117 ret i32 %b 118} 119 120; CHECK-LABEL: one_f64: 121; CHECK-NEXT: .functype one_f64 (f64, f64) -> (i32){{$}} 122; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 123; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 124; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 125; CHECK-NEXT: local.get $push[[L2:[0-9]+]]=, 0{{$}} 126; CHECK-NEXT: local.get $push[[L3:[0-9]+]]=, 0{{$}} 127; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 128; CHECK-NEXT: local.get $push[[L4:[0-9]+]]=, 1{{$}} 129; CHECK-NEXT: local.get $push[[L5:[0-9]+]]=, 1{{$}} 130; CHECK-NEXT: f64.eq $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 131; CHECK-NEXT: i32.and $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}} 132; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}} 133; CHECK-NEXT: return $pop[[NUM4]] 134define i32 @one_f64(double %x, double %y) { 135 %a = fcmp one double %x, %y 136 %b = zext i1 %a to i32 137 ret i32 %b 138} 139 140; CHECK-LABEL: ult_f64: 141; CHECK-NEXT: .functype ult_f64 (f64, f64) -> (i32){{$}} 142; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 143; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 144; CHECK-NEXT: f64.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 145; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 146; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 147; CHECK-NEXT: return $pop[[NUM2]]{{$}} 148define i32 @ult_f64(double %x, double %y) { 149 %a = fcmp ult double %x, %y 150 %b = zext i1 %a to i32 151 ret i32 %b 152} 153 154; CHECK-LABEL: ule_f64: 155; CHECK-NEXT: .functype ule_f64 (f64, f64) -> (i32){{$}} 156; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 157; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 158; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 159; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 160; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 161; CHECK-NEXT: return $pop[[NUM2]]{{$}} 162define i32 @ule_f64(double %x, double %y) { 163 %a = fcmp ule double %x, %y 164 %b = zext i1 %a to i32 165 ret i32 %b 166} 167 168; CHECK-LABEL: ugt_f64: 169; CHECK-NEXT: .functype ugt_f64 (f64, f64) -> (i32){{$}} 170; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 171; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 172; CHECK-NEXT: f64.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 173; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 174; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 175; CHECK-NEXT: return $pop[[NUM2]]{{$}} 176define i32 @ugt_f64(double %x, double %y) { 177 %a = fcmp ugt double %x, %y 178 %b = zext i1 %a to i32 179 ret i32 %b 180} 181 182; CHECK-LABEL: uge_f64: 183; CHECK-NEXT: .functype uge_f64 (f64, f64) -> (i32){{$}} 184; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}} 185; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}} 186; CHECK-NEXT: f64.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 187; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 188; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 189; CHECK-NEXT: return $pop[[NUM2]]{{$}} 190define i32 @uge_f64(double %x, double %y) { 191 %a = fcmp uge double %x, %y 192 %b = zext i1 %a to i32 193 ret i32 %b 194} 195