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 6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7 target 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]]{{$}} 20 define 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]]{{$}} 37 define 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]]{{$}} 50 define 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]]{{$}} 59 define 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]]{{$}} 68 define 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]]{{$}} 77 define 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]]{{$}} 86 define 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]]{{$}} 95 define 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]]{{$}} 118 define 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]] 139 define 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]]{{$}} 154 define 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]]{{$}} 169 define 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]]{{$}} 184 define 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]]{{$}} 199 define 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