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